├── .gitignore
├── README.md
├── pom.xml
└── src
└── main
└── java
└── dumaisoft
├── chapter01
└── BinarySearch.java
├── chapter02
└── SelectionSort.java
├── chapter03
├── CountDown.java
└── Factorial.java
├── chapter04
├── QuickSort.java
└── QuickSortForArray.java
├── chapter05
└── HashtableExample.java
├── chapter06
└── BreadthFristSearch.java
├── chapter07
└── Dijkstra.java
├── chapter08
└── Greed.java
├── chapter09
└── FindLongestPublicSubString.java
└── chapter10
└── KNN.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | bin
3 | .settings
4 | .project
5 | .classpath
6 | .idea
7 | .DS_Store
8 | *.iml
9 | /.idea
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 《算法图解》 中所有例子的Java版实现
2 |
3 | >代码已经更新到第10章
4 |
5 | [《算法图解》的购买地址](https://item.jd.com/12148832.html)
6 |
7 |
8 | ## 内容提要
9 |
10 | 《算法图解》中所有的例子都使用Python实现,我们提供了这本书的所有Java实现代码,供Java程序员看书时使用。
11 |
12 | chapter01:BinarySearch,二分排序算法
13 |
14 | chapter02:SelectionSort,选择排序算法
15 |
16 | chapter03:递归算法,CountDown和Factorial的例子
17 |
18 | chapter04:Quick Sort快速排序,书上的例子用QuickSort实现,它对List排序,中间产生了很多临时List对象,效率较低;
19 | 因此还提供了为原生数组排序的QuickSortForArray算法,不产生临时对象,效率较高
20 |
21 | chapter05:Hash table simple example,哈希表的简单范例。
22 |
23 | chapter06:广度优先搜索 breadth-first search,寻找有向图中的最短路径
24 |
25 | chapter07:dijkstra's algorithm, 寻找有向无环加权图中的最短路径
26 |
27 | chapter08:Greed,贪心算法解决集合覆盖问题
28 |
29 | chapter09:FindLongestPublicSubString,使用动态规划算来寻找"最长公共子序列"和"最长公共子串"
30 |
31 | chapter10:KNN,使用knn算法来预测面包店的销量(本算法书中并无代码)
32 |
33 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | dumaisoft
6 | Grokking_algorithms_in_java
7 | 1.0-SNAPSHOT
8 | jar
9 |
10 | Grokking_algorithms_in_java
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 |
16 |
17 |
18 |
19 | junit
20 | junit
21 | 3.8.1
22 | test
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter01/BinarySearch.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter01;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | /**
8 | * Created by wxb on 2017/12/8 0008.
9 | */
10 | public class BinarySearch {
11 | public static void main(String[] args) {
12 | List list = new ArrayList(Arrays.asList(1, 3, 5, 7, 9));
13 | int index = binary_search(list, 3);
14 | if (index > -1) {
15 | System.out.println("find item, index = " + index);
16 | }
17 | }
18 |
19 | private static int binary_search(List list, int item) {
20 | int low = 0;
21 | int high = list.size() - 1;
22 | while (low <= high) {
23 | int mid = (low + high) / 2;
24 | int guess = list.get(mid);
25 | if (guess == item) {
26 | return mid;
27 | }
28 | if (guess > item) {
29 | high = mid - 1;
30 | } else {
31 | low = mid + 1;
32 | }
33 | }
34 | return -1;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter02/SelectionSort.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter02;
2 |
3 | import java.util.Arrays;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | /**
8 | * Created by wxb on 2017/12/10 0010.
9 | */
10 | public class SelectionSort {
11 | public static void main(String[] args) {
12 | List list = new LinkedList(Arrays.asList(5, 3, 6, 2, 10));
13 | List sortedList = selectionSort(list);
14 | System.out.println(sortedList);
15 | }
16 |
17 | private static List selectionSort(List list) {
18 | List newArr = new LinkedList();
19 | while (!list.isEmpty()) {
20 | int smallest_index = findSmallest(list);
21 | newArr.add(list.remove(smallest_index));
22 | }
23 | return newArr;
24 | }
25 |
26 | private static int findSmallest(List list) {
27 | int smallest = list.get(0);
28 | int smallest_index = 0;
29 | for (int i = 1; i < list.size(); i++) {
30 | if (list.get(i) < smallest) {
31 | smallest = list.get(i);
32 | smallest_index = i;
33 | }
34 | }
35 | return smallest_index;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter03/CountDown.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter03;
2 |
3 | /**
4 | * Author: wxb
5 | * Project: Grokking_algorithms_in_java
6 | * Create Date: 2017/12/13
7 | * Create Time: 20:39
8 | * Description: simple example for recursion function
9 | */
10 | public class CountDown {
11 | public static void main(String[] args) {
12 | countDown(5);
13 | }
14 |
15 | private static void countDown(int i) {
16 | System.out.println(i);
17 | if (i <= 0) {
18 | return;
19 | } else {
20 | countDown(i - 1);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter03/Factorial.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter03;
2 |
3 | /**
4 | * Author: wxb
5 | * Project: Grokking_algorithms_in_java
6 | * Create Date: 2017/12/13
7 | * Create Time: 20:36
8 | * Description: compute the factorial number
9 | */
10 | public class Factorial {
11 | public static void main(String[] args) {
12 | int n = factorail(5);
13 | System.out.println(n);
14 | }
15 |
16 | private static int factorail(int x) {
17 | if (x == 0) {
18 | return 1;
19 | }
20 | return x*factorail(x-1);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter04/QuickSort.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter04;
2 |
3 | import java.util.Arrays;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | /**
8 | * Author: wxb
9 | * Project: Grokking_algorithms_in_java
10 | * Create Date: 2017/12/13
11 | * Create Time: 20:42
12 | * Description: quick sort algorithm , for List
13 | */
14 | public class QuickSort {
15 | public static void main(String[] args) {
16 | List list = new LinkedList(Arrays.asList(10, 5, 2, 3));
17 | System.out.println(quicksort(list));
18 | }
19 |
20 | private static List quicksort(List list) {
21 | if (list.size() < 2) {
22 | return list;
23 | }
24 | int pivot = list.get(0);
25 | List less = new LinkedList();
26 | List greater = new LinkedList();
27 | for (int i = 1; i < list.size(); i++) {
28 | if (list.get(i) <= pivot) {
29 | less.add(list.get(i));
30 | } else {
31 | greater.add(list.get(i));
32 | }
33 | }
34 |
35 | List lessSorted = quicksort(less);
36 | List greaterSorted = quicksort(greater);
37 | List result = new LinkedList(lessSorted);
38 | result.add(pivot);
39 | result.addAll(greaterSorted);
40 | return result;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter04/QuickSortForArray.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter04;
2 |
3 | /**
4 | * Author: wxb
5 | * Project: Grokking_algorithms_in_java
6 | * Create Date: 2017/12/13
7 | * Create Time: 21:09
8 | * Description: quick sort for array
9 | */
10 | public class QuickSortForArray {
11 | public static void main(String[] args) {
12 | int[] array = {5, 2, 3, 10};
13 | quicksort(array, 0, array.length - 1);
14 | printArray(array);
15 | }
16 |
17 | private static void printArray(int[] array) {
18 | System.out.print("[ ");
19 | for (int i = 0; i < array.length; i++) {
20 | System.out.print(array[i] + " ");
21 | }
22 | System.out.println("]");
23 | }
24 |
25 | private static void quicksort(int[] array, int begin, int end) {
26 | if (begin >= end) return;
27 | int mid = partition(array, begin, end);
28 | quicksort(array, begin, mid - 1);
29 | quicksort(array, mid + 1, end);
30 | }
31 |
32 | private static int partition(int[] array, int begin, int end) {
33 | int x = array[begin];
34 | int smallIndex = begin;
35 | int bigIndex = begin;
36 | while (++bigIndex <= end) {
37 | if (array[bigIndex] >= x) continue;
38 | else {
39 | smallIndex++;
40 | swap(array, smallIndex, bigIndex);
41 | }
42 | }
43 | swap(array, begin, smallIndex);
44 | return smallIndex;
45 | }
46 |
47 | private static void swap(int[] array, int lhs, int rhs) {
48 | int temp = array[lhs];
49 | array[lhs] = array[rhs];
50 | array[rhs] = temp;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter05/HashtableExample.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter05;
2 |
3 | import java.util.HashMap;
4 |
5 | /**
6 | * Author: wxb
7 | * Project: Grokking_algorithms_in_java
8 | * Create Date: 2017/12/14
9 | * Create Time: 20:08
10 | * Description: simple example for hash table.
11 | */
12 | public class HashtableExample {
13 | public static void main(String[] args) {
14 | HashMap book = new HashMap();
15 | book.put("apple", 0.67F);
16 | book.put("milk", 1.49F);
17 | book.put("avocado", 1.49F);
18 | System.out.println(book);
19 | System.out.println(book.get("avocado"));
20 |
21 | HashMap voted = new HashMap();
22 | check_voter(voted, "tom");
23 | check_voter(voted, "mike");
24 | check_voter(voted, "mike");
25 | }
26 |
27 | private static void check_voter(HashMap voted, String name) {
28 | if (voted.get(name) != null && voted.get(name)) {
29 | System.out.println("kick them out!");
30 | } else {
31 | voted.put(name, true);
32 | System.out.println("let them vote");
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter06/BreadthFristSearch.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter06;
2 |
3 | import java.util.*;
4 |
5 | /**
6 | * Author: wxb
7 | * Project: Grokking_algorithms_in_java
8 | * Create Date: 2017/12/14
9 | * Create Time: 20:40
10 | * Description: simple example for breadth-first search in a graph.
11 | */
12 | public class BreadthFristSearch {
13 | public static void main(String[] args) {
14 | HashMap> graph = new HashMap>();
15 | graph.put("you", new LinkedList(Arrays.asList("alice", "bob", "claire")));
16 | graph.put("bob", new LinkedList(Arrays.asList("anuj", "peggy")));
17 | graph.put("alice", new LinkedList(Arrays.asList("peggy")));
18 | graph.put("claire", new LinkedList(Arrays.asList("thom", "jonny")));
19 | graph.put("anuj", new LinkedList());
20 | graph.put("peggy", new LinkedList());
21 | graph.put("thom", new LinkedList());
22 | graph.put("jonny", new LinkedList());
23 |
24 | LinkedList search_queue = new LinkedList();
25 | LinkedList searched = new LinkedList();
26 |
27 | search_queue.addAll(graph.get("you"));
28 | while (!search_queue.isEmpty()) {
29 | String person = search_queue.poll();
30 | if (!searched.contains(person)) {
31 | if (person_is_seller(person)) {
32 | System.out.println(person + " is a mango seller!");
33 | return;
34 | } else {
35 | search_queue.addAll(graph.get(person));
36 | searched.add(person);
37 | }
38 | }
39 | }
40 | System.out.println("there is no mango seller!");
41 | }
42 |
43 | private static boolean person_is_seller(String name) {
44 | return name.endsWith("m");
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter07/Dijkstra.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter07;
2 |
3 | import java.util.HashMap;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | /**
9 | * Created by wxb on 2017/12/16 0016.
10 | */
11 | public class Dijkstra {
12 | public static void main(String[] args) {
13 | //create and initialize graph
14 | HashMap> graph = new HashMap>();
15 | graph.put("start", new HashMap() {
16 | {
17 | put("a", 6f);
18 | put("b", 2f);
19 | }
20 | });
21 | graph.put("a", new HashMap() {
22 | {
23 | put("fin", 1f);
24 | }
25 | });
26 | graph.put("b", new HashMap() {
27 | {
28 | put("a", 3f);
29 | put("fin", 5f);
30 | }
31 | });
32 | graph.put("fin", new HashMap());
33 |
34 | HashMap costs = new HashMap() {
35 | {
36 | put("a", 6f);
37 | put("b", 2f);
38 | put("fin", Float.POSITIVE_INFINITY);
39 | }
40 | };
41 |
42 | HashMap parents = new HashMap() {
43 | {
44 | put("a", "start");
45 | put("b", "start");
46 | put("fin", null);
47 | }
48 | };
49 | List processed = new LinkedList();
50 | //dijkstra's algorithm
51 | String node = find_lowest_cost_node(costs, processed);
52 | while (node != null) {
53 | float cost = costs.get(node);
54 | HashMap neighbors = graph.get(node);
55 | //遍历当前节点的所有邻居
56 | for (Map.Entry entry : neighbors.entrySet()) {
57 | String n = entry.getKey();
58 | float new_cost = entry.getValue() +cost;
59 | if (costs.get(n) > new_cost) {
60 | costs.remove(n);
61 | costs.put(n, new_cost);
62 | parents.remove(n);
63 | parents.put(n, node);
64 | }
65 | }
66 | processed.add(node);
67 | node = find_lowest_cost_node(costs, processed);
68 | }
69 | System.out.println(costs);
70 | System.out.println(parents);
71 | printResult(costs, parents);
72 | }
73 |
74 | /**
75 | * 打印Dijkstra算法的结果
76 | * @param costs
77 | * @param parents
78 | */
79 | private static void printResult(HashMap costs, HashMap parents) {
80 | System.out.print("The path is : start-->");
81 | String node = findParent(parents, "start");
82 | while (node != null && !node.equals("fin")) {
83 | String parent = findParent(parents, node);
84 | System.out.print(node + "-->");
85 | node = parent;
86 | }
87 | System.out.println("fin");
88 | System.out.println("The total cost is : "+costs.get("fin"));
89 | }
90 |
91 | private static String findParent(HashMap parents, String node) {
92 | for (Map.Entry entry : parents.entrySet()) {
93 | if (entry.getValue().equals(node)) {
94 | return entry.getKey();
95 | }
96 | }
97 | return null;
98 | }
99 |
100 | private static String find_lowest_cost_node(HashMap costs, List processed) {
101 | float lowest_cost = Float.POSITIVE_INFINITY;
102 | String lowest_cost_node = null;
103 | for (Map.Entry entry : costs.entrySet()) {
104 | float cost = entry.getValue();
105 | if (cost < lowest_cost && !processed.contains(entry.getKey())) {
106 | lowest_cost = cost;
107 | lowest_cost_node = entry.getKey();
108 | }
109 | }
110 | return lowest_cost_node;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter08/Greed.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter08;
2 |
3 | import java.util.*;
4 |
5 | /**
6 | * Created by wxb on 2017/12/19 0019.
7 | */
8 | public class Greed {
9 | public static void main(String[] args) {
10 | Set states_needed = new HashSet(Arrays.asList("mt", "wa", "or", "id", "nv", "ut", "ca", "az"));
11 | Map> stations = new HashMap>() {
12 | {
13 | put("kone", new HashSet(Arrays.asList("id", "nv", "ut")));
14 | put("ktwo", new HashSet(Arrays.asList("wa", "id", "mt")));
15 | put("kthree", new HashSet(Arrays.asList("or", "nv", "ca")));
16 | put("kfour", new HashSet(Arrays.asList("nv", "ut")));
17 | put("kfive", new HashSet(Arrays.asList("ca", "az")));
18 | }
19 | };
20 | Set final_stations = new HashSet();
21 | String best_station = null;
22 | Set states_covered = null;
23 | while (!states_needed.isEmpty()) {
24 | best_station = null;
25 | states_covered = new HashSet();
26 | for (Map.Entry> entry : stations.entrySet()) {
27 | Set covered = entry.getValue();
28 | covered.retainAll(states_needed);
29 | if (covered.size() > states_covered.size()) {
30 | best_station = entry.getKey();
31 | states_covered = covered;
32 | }
33 | }
34 | final_stations.add(best_station);
35 | states_needed.removeAll(states_covered);
36 | }
37 | System.out.println("the result is : " + final_stations);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter09/FindLongestPublicSubString.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter09;
2 |
3 | /**
4 | * Created by wxb on 2017/12/19 0019.
5 | * 使用动态规划算来寻找"最长的公共子序列"
6 | */
7 | public class FindLongestPublicSubString {
8 | public static void main(String[] args) {
9 | String word_a = "fosh";
10 | String word_b = "fish";
11 | int maxSubSequence = findLongestPublicSubSequence(word_a, word_b);
12 | System.out.println("the longest public sub sequence is : " + maxSubSequence);
13 | int maxSubString = findLongestPublicSubString(word_a, word_b);
14 | System.out.println("the longest public sub string is : " + maxSubString);
15 | }
16 |
17 | /**
18 | * 寻找最长公共子串
19 | *
20 | * @param word_a
21 | * @param word_b
22 | * @return
23 | */
24 | private static int findLongestPublicSubString(String word_a, String word_b) {
25 | int[][] cell = new int[word_a.length()][word_b.length()];
26 | for (int i = 0; i < word_a.length(); i++) {
27 | for (int j = 0; j < word_b.length(); j++) {
28 | if (word_a.charAt(i) == word_b.charAt(j)) {
29 | if (i > 0 && j > 0) {
30 | cell[i][j] = cell[i - 1][j - 1] + 1;
31 | } else {
32 | cell[i][j] = 1;
33 | }
34 | } else {
35 | cell[i][j] = 0;
36 | }
37 | }
38 | }
39 | int maxLength = 0;
40 | for (int i = 0; i < word_a.length(); i++) {
41 | for (int j = 0; j < word_b.length(); j++) {
42 | maxLength = Math.max(maxLength, cell[i][j]);
43 | }
44 | }
45 | return maxLength;
46 | }
47 |
48 | /**
49 | * 寻找最长公共子序列
50 | *
51 | * @param word_a
52 | * @param word_b
53 | * @return
54 | */
55 | private static int findLongestPublicSubSequence(String word_a, String word_b) {
56 | int[][] cell = new int[word_a.length()][word_b.length()];
57 | for (int i = 0; i < word_a.length(); i++) {
58 | for (int j = 0; j < word_b.length(); j++) {
59 | if (word_a.charAt(i) == word_b.charAt(j)) {
60 | if (i > 0 && j > 0) {
61 | cell[i][j] = cell[i - 1][j - 1] + 1;
62 | } else {
63 | cell[i][j] = 1;
64 | }
65 | } else {
66 | if (i > 0 && j > 0) {
67 | cell[i][j] = Math.max(cell[i - 1][j], cell[i][j - 1]);
68 | } else if (i > 0) {
69 | cell[i][j] = cell[i - 1][j];
70 | } else if (j > 0) {
71 | cell[i][j] = cell[i][j - 1];
72 | } else {
73 | cell[i][j] = 0;
74 | }
75 | }
76 | }
77 | }
78 | int maxLength = 0;
79 | for (int i = 0; i < word_a.length(); i++) {
80 | for (int j = 0; j < word_b.length(); j++) {
81 | maxLength = Math.max(maxLength, cell[i][j]);
82 | }
83 | }
84 | return maxLength;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/dumaisoft/chapter10/KNN.java:
--------------------------------------------------------------------------------
1 | package dumaisoft.chapter10;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by wxb on 2017/12/24 0024.
8 | * using knn algorithm to predict
9 | */
10 | public class KNN {
11 |
12 | private static class BreadNumber {
13 | int weather;
14 | int isHoliday;
15 | int isActivity;
16 | int number;
17 | float distance;
18 |
19 | public BreadNumber(int weather, int isHoliday, int isActivity, int number) {
20 | this.weather = weather;
21 | this.isHoliday = isHoliday;
22 | this.isActivity = isActivity;
23 | this.number = number;
24 | }
25 | }
26 |
27 | public static void main(String[] args) {
28 | List breadNumbers = new LinkedList() {
29 | {
30 | add(new BreadNumber(5, 1, 0, 300));
31 | add(new BreadNumber(3, 1, 1, 225));
32 | add(new BreadNumber(1, 1, 0, 75));
33 | add(new BreadNumber(4, 0, 0, 200));
34 | add(new BreadNumber(4, 0, 0, 150));
35 | add(new BreadNumber(2, 0, 0, 50));
36 | }
37 | };
38 | BreadNumber today = new BreadNumber(4, 1, 0, 0);
39 | float prediction = knn(breadNumbers, today, 4);
40 | System.out.println(prediction);
41 | }
42 |
43 | /**
44 | * @param breadNumbers : 所有的历史数据
45 | * @param today :要预测的数据组合
46 | * @param k :参数k,这里为4
47 | * @return
48 | */
49 | private static float knn(List breadNumbers, BreadNumber today, int k) {
50 | //计算所有邻居的距离
51 | for (BreadNumber breadNumber : breadNumbers) {
52 | float distance = computeDistance(breadNumber, today);
53 | breadNumber.distance = distance;
54 | }
55 | //寻找最近的k个邻居加入neighbors
56 | List neighbors = new LinkedList();
57 | while (k > 0 && !breadNumbers.isEmpty()) {
58 | float nearest = Float.MAX_VALUE;
59 | BreadNumber nearestNeighbor = null;
60 | for (BreadNumber breadNumber : breadNumbers) {
61 | if (breadNumber.distance < nearest) {
62 | nearestNeighbor = breadNumber;
63 | nearest = breadNumber.distance;
64 | }
65 | }
66 | k--;
67 | neighbors.add(nearestNeighbor);
68 | breadNumbers.remove(nearestNeighbor);
69 | }
70 | //预测today的销量
71 | float todayNumber = 0;
72 | for (BreadNumber neighbor : neighbors) {
73 | todayNumber += neighbor.number;
74 | }
75 | return todayNumber / neighbors.size();
76 | }
77 |
78 | /**
79 | * 计算两个邻居之间的距离
80 | * @param breadNumber
81 | * @param today
82 | * @return
83 | */
84 | private static float computeDistance(BreadNumber breadNumber, BreadNumber today) {
85 | return (float) Math.sqrt(Math.pow((breadNumber.weather - today.weather), 2) +
86 | Math.pow((breadNumber.isHoliday - today.isHoliday), 2) +
87 | Math.pow((breadNumber.isActivity - today.isActivity), 2));
88 | }
89 | }
90 |
--------------------------------------------------------------------------------