Skip to content

Commit f7fecc6

Browse files
committed
Add algorithm to find center node(s)
1 parent 3d2904a commit f7fecc6

File tree

14 files changed

+154
-37
lines changed

14 files changed

+154
-37
lines changed

src/main/java/com/williamfiset/algorithms/dp/examples/HouseRobber.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
*
66
* <p>Download the code: $ git clone https://github.com/williamfiset/Algorithms
77
*
8-
* <p>Change directory to the root of the Algorithms directory:
9-
* <p> $ cd Algorithms
8+
* <p>Change directory to the root of the Algorithms directory:
109
*
11-
* <p>Build: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/dp/examples/HouseRobber.java
10+
* <p>$ cd Algorithms
11+
*
12+
* <p>Build: $ javac -d src/main/java
13+
* src/main/java/com/williamfiset/algorithms/dp/examples/HouseRobber.java
1214
*
1315
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/dp/examples/HouseRobber
1416
*/

src/main/java/com/williamfiset/algorithms/graphtheory/examples/EagerPrimsExample.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
*
77
* <p>Change directory to the root of the Algorithms directory: $ cd Algorithms
88
*
9-
* <p>Compile: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/graphtheory/examples/EagerPrimsExample.java
9+
* <p>Compile: $ javac -d src/main/java
10+
* src/main/java/com/williamfiset/algorithms/graphtheory/examples/EagerPrimsExample.java
1011
*
11-
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/graphtheory/examples/EagerPrimsExample
12+
* <p>Run: $ java -cp src/main/java
13+
* com/williamfiset/algorithms/graphtheory/examples/EagerPrimsExample
1214
*
1315
* <p>Time Complexity: O(ElogV)
1416
*

src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/CapacityScalingExample.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
*
1010
* <p>Change directory to the root of the Algorithms directory: $ cd Algorithms
1111
*
12-
* <p>Build: $ javac src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/CapacityScalingExample.java
12+
* <p>Build: $ javac
13+
* src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/CapacityScalingExample.java
1314
*
14-
* <p>Run: $ java -cp src/main/java/ com/williamfiset/algorithms/graphtheory/networkflow/examples/CapacityScalingExample
15+
* <p>Run: $ java -cp src/main/java/
16+
* com/williamfiset/algorithms/graphtheory/networkflow/examples/CapacityScalingExample
1517
*/
1618
package com.williamfiset.algorithms.graphtheory.networkflow.examples;
1719

src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/DinicsExample.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
*
99
* <p>Change directory to the root of the Algorithms directory: $ cd Algorithms
1010
*
11-
* <p>Build: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/DinicsExample.java
11+
* <p>Build: $ javac -d src/main/java
12+
* src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/DinicsExample.java
1213
*
13-
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/graphtheory/networkflow/examples/DinicsExample
14+
* <p>Run: $ java -cp src/main/java
15+
* com/williamfiset/algorithms/graphtheory/networkflow/examples/DinicsExample
1416
*/
1517
package com.williamfiset.algorithms.graphtheory.networkflow.examples;
1618

src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/EdmondsKarpExample.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
*
88
* <p>Change directory to the root of the Algorithms directory: $ cd Algorithms
99
*
10-
* <p>Build: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/EdmondsKarpExample.java
10+
* <p>Build: $ javac -d src/main/java
11+
* src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/EdmondsKarpExample.java
1112
*
12-
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/graphtheory/networkflow/examples/EdmondsKarpExample
13+
* <p>Run: $ java -cp src/main/java
14+
* com/williamfiset/algorithms/graphtheory/networkflow/examples/EdmondsKarpExample
1315
*/
1416
package com.williamfiset.algorithms.graphtheory.networkflow.examples;
1517

src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/FordFulkersonExample.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
*
99
* <p>Change directory to the root of the Algorithms directory: $ cd Algorithms
1010
*
11-
* <p>Build: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/FordFulkersonExample.java
11+
* <p>Build: $ javac -d src/main/java
12+
* src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/FordFulkersonExample.java
1213
*
13-
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/graphtheory/networkflow/examples/FordFulkersonExample
14+
* <p>Run: $ java -cp src/main/java
15+
* com/williamfiset/algorithms/graphtheory/networkflow/examples/FordFulkersonExample
1416
*/
1517
package com.williamfiset.algorithms.graphtheory.networkflow.examples;
1618

src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/MiceAndOwls.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
*
44
* <p>Change directory to the root of the Algorithms directory: $ cd Algorithms
55
*
6-
* <p>Build: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/MiceAndOwls.java
6+
* <p>Build: $ javac -d src/main/java
7+
* src/main/java/com/williamfiset/algorithms/graphtheory/networkflow/examples/MiceAndOwls.java
78
*
8-
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/graphtheory/networkflow/examples/MiceAndOwls
9+
* <p>Run: $ java -cp src/main/java
10+
* com/williamfiset/algorithms/graphtheory/networkflow/examples/MiceAndOwls
911
*/
1012
package com.williamfiset.algorithms.graphtheory.networkflow.examples;
1113

src/main/java/com/williamfiset/algorithms/graphtheory/treealgorithms/TreeCenterLongestPathImpl.java

+12-11
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
public class TreeCenterLongestPathImpl {
1616

17-
private static int[] dfs(List<List<Integer>> graph, boolean[] visited, int[] prev, int at, int parent) {
17+
private static int[] dfs(
18+
List<List<Integer>> graph, boolean[] visited, int[] prev, int at, int parent) {
1819

1920
// Already visited this node
2021
if (visited[at]) return new int[] {0, parent};
@@ -40,7 +41,7 @@ private static int[] dfs(List<List<Integer>> graph, boolean[] visited, int[] pre
4041
return new int[] {bestDist, index};
4142
}
4243

43-
public static List<Integer> treeCenter(List<List<Integer>> graph) {
44+
public static List<Integer> findTreeCenters(List<List<Integer>> graph) {
4445
List<Integer> centers = new ArrayList<>();
4546
if (graph == null) return centers;
4647

@@ -68,13 +69,13 @@ public static List<Integer> treeCenter(List<List<Integer>> graph) {
6869
}
6970

7071
if (path.size() % 2 == 0) {
71-
centers.add(path.get(path.size()/2-1));
72+
centers.add(path.get(path.size() / 2 - 1));
7273
}
73-
centers.add(path.get(path.size()/2));
74+
centers.add(path.get(path.size() / 2));
7475
return centers;
7576
}
7677

77-
/** ********** TESTING ********* */
78+
/** ********** TESTING ********* */
7879

7980
// Create an empty tree as a adjacency list.
8081
public static List<List<Integer>> createEmptyTree(int n) {
@@ -101,29 +102,29 @@ public static void main(String[] args) {
101102
addUndirectedEdge(graph, 6, 8);
102103

103104
// Centers are 2
104-
System.out.println(treeCenter(graph)+"\n");
105+
System.out.println(findTreeCenters(graph) + "\n");
105106

106107
// Centers are 0
107108
List<List<Integer>> graph2 = createEmptyTree(1);
108-
System.out.println(treeCenter(graph2)+"\n");
109+
System.out.println(findTreeCenters(graph2) + "\n");
109110

110111
// Centers are 0,1
111112
List<List<Integer>> graph3 = createEmptyTree(2);
112113
addUndirectedEdge(graph3, 0, 1);
113-
System.out.println(treeCenter(graph3)+"\n");
114+
System.out.println(findTreeCenters(graph3) + "\n");
114115

115116
// Centers are 1
116117
List<List<Integer>> graph4 = createEmptyTree(3);
117118
addUndirectedEdge(graph4, 0, 1);
118119
addUndirectedEdge(graph4, 1, 2);
119-
System.out.println(treeCenter(graph4)+"\n");
120+
System.out.println(findTreeCenters(graph4) + "\n");
120121

121122
// Centers are 1,2
122123
List<List<Integer>> graph5 = createEmptyTree(4);
123124
addUndirectedEdge(graph5, 0, 1);
124125
addUndirectedEdge(graph5, 1, 2);
125126
addUndirectedEdge(graph5, 2, 3);
126-
System.out.println(treeCenter(graph5)+"\n");
127+
System.out.println(findTreeCenters(graph5) + "\n");
127128

128129
// Centers are 2,3
129130
List<List<Integer>> graph6 = createEmptyTree(7);
@@ -133,6 +134,6 @@ public static void main(String[] args) {
133134
addUndirectedEdge(graph6, 3, 4);
134135
addUndirectedEdge(graph6, 4, 5);
135136
addUndirectedEdge(graph6, 4, 6);
136-
System.out.println(treeCenter(graph6)+"\n");
137+
System.out.println(findTreeCenters(graph6) + "\n");
137138
}
138139
}

src/main/java/com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeHeight.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
*
66
* <p>Change directory to the root of the Algorithms directory: $ cd Algorithms
77
*
8-
* <p>Compile: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeHeight.java
8+
* <p>Compile: $ javac -d src/main/java
9+
* src/main/java/com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeHeight.java
910
*
10-
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeHeight
11+
* <p>Run: $ java -cp src/main/java
12+
* com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeHeight
1113
*
1214
* <p>Time Complexity: O(n)
1315
*

src/main/java/com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeSum.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
*
66
* <p>Change directory to the root of the Algorithms directory: $ cd Algorithms
77
*
8-
* <p>Compile: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeSum.java
8+
* <p>Compile: $ javac -d src/main/java
9+
* src/main/java/com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeSum.java
910
*
10-
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeSum
11+
* <p>Run: $ java -cp src/main/java
12+
* com/williamfiset/algorithms/graphtheory/treealgorithms/examples/TreeSum
1113
*
1214
* <p>Time Complexity: O(n)
1315
*

src/main/java/com/williamfiset/algorithms/math/CompressedPrimeSieve.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
*
88
* <p>Time Complexity: ~O(nloglogn)
99
*
10-
* <p>Compile: javac -d src/main/java src/main/java/com/williamfiset/algorithms/math/CompressedPrimeSieve.java
10+
* <p>Compile: javac -d src/main/java
11+
* src/main/java/com/williamfiset/algorithms/math/CompressedPrimeSieve.java
1112
*
1213
* <p>Run: java -cp src/main/java com/williamfiset/algorithms/math/CompressedPrimeSieve
1314
*

src/main/java/com/williamfiset/algorithms/strings/LongestCommonSubstring.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
*
66
* <p>Run on command line:
77
*
8-
* <p>Compile: $ javac -d src/main/java src/main/java/com/williamfiset/algorithms/strings/LongestCommonSubstring.java
8+
* <p>Compile: $ javac -d src/main/java
9+
* src/main/java/com/williamfiset/algorithms/strings/LongestCommonSubstring.java
910
*
1011
* <p>Run: $ java -cp src/main/java com/williamfiset/algorithms/strings/LongestCommonSubstring
1112
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// To run this test in isolation from root folder:
2+
//
3+
// $ gradle test --tests
4+
// com.williamfiset.algorithms.graphtheory.treealgorithms.TreeCenterLongestPathImplTest
5+
6+
package com.williamfiset.algorithms.graphtheory.treealgorithms;
7+
8+
import static com.google.common.truth.Truth.assertThat;
9+
import static com.williamfiset.algorithms.graphtheory.treealgorithms.TreeCenterLongestPathImpl.addUndirectedEdge;
10+
import static com.williamfiset.algorithms.graphtheory.treealgorithms.TreeCenterLongestPathImpl.createEmptyTree;
11+
import static com.williamfiset.algorithms.graphtheory.treealgorithms.TreeCenterLongestPathImpl.findTreeCenters;
12+
13+
import java.util.*;
14+
import org.junit.*;
15+
16+
public class TreeCenterLongestPathImplTest {
17+
18+
@Test
19+
public void simpleTest1() {
20+
List<List<Integer>> graph = createEmptyTree(9);
21+
addUndirectedEdge(graph, 0, 1);
22+
addUndirectedEdge(graph, 2, 1);
23+
addUndirectedEdge(graph, 2, 3);
24+
addUndirectedEdge(graph, 3, 4);
25+
addUndirectedEdge(graph, 5, 3);
26+
addUndirectedEdge(graph, 2, 6);
27+
addUndirectedEdge(graph, 6, 7);
28+
addUndirectedEdge(graph, 6, 8);
29+
assertThat(findTreeCenters(graph)).containsExactly(2);
30+
}
31+
32+
@Test
33+
public void singleton() {
34+
assertThat(findTreeCenters(createEmptyTree(1))).containsExactly(0);
35+
}
36+
37+
@Test
38+
public void twoNodeTree() {
39+
List<List<Integer>> graph = createEmptyTree(2);
40+
addUndirectedEdge(graph, 0, 1);
41+
assertThat(findTreeCenters(graph)).containsExactly(0, 1);
42+
}
43+
44+
@Test
45+
public void simpleTest2() {
46+
List<List<Integer>> graph = createEmptyTree(3);
47+
addUndirectedEdge(graph, 0, 1);
48+
addUndirectedEdge(graph, 1, 2);
49+
assertThat(findTreeCenters(graph)).containsExactly(1);
50+
}
51+
52+
@Test
53+
public void simpleTest3() {
54+
List<List<Integer>> graph = createEmptyTree(4);
55+
addUndirectedEdge(graph, 0, 1);
56+
addUndirectedEdge(graph, 1, 2);
57+
addUndirectedEdge(graph, 2, 3);
58+
assertThat(findTreeCenters(graph)).containsExactly(1, 2);
59+
}
60+
61+
@Test
62+
public void simpleTest4() {
63+
List<List<Integer>> graph = createEmptyTree(7);
64+
addUndirectedEdge(graph, 0, 1);
65+
addUndirectedEdge(graph, 1, 2);
66+
addUndirectedEdge(graph, 2, 3);
67+
addUndirectedEdge(graph, 3, 4);
68+
addUndirectedEdge(graph, 4, 5);
69+
addUndirectedEdge(graph, 4, 6);
70+
assertThat(findTreeCenters(graph)).containsExactly(2, 3);
71+
}
72+
}

src/test/java/com/williamfiset/algorithms/graphtheory/treealgorithms/TreeCenterTest.java

+29-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515

1616
public class TreeCenterTest {
1717

18-
@Test
19-
public void emptyTreeThrowsException() {
20-
assertThat(createEmptyTree(0)).isEmpty();
21-
}
22-
2318
@Test
2419
public void simpleTest1() {
2520
List<List<Integer>> graph = createEmptyTree(9);
@@ -74,4 +69,33 @@ public void simpleTest4() {
7469
addUndirectedEdge(graph, 4, 6);
7570
assertThat(findTreeCenters(graph)).containsExactly(2, 3);
7671
}
72+
73+
@Test
74+
public void testTreeCenterVsOtherImpl() {
75+
for (int n = 1; n < 500; n++) {
76+
for (int loops = 0; loops < 100; loops++) {
77+
List<List<Integer>> tree = generateRandomTree(n);
78+
79+
List<Integer> impl1 = findTreeCenters(tree);
80+
List<Integer> impl2 =
81+
com.williamfiset.algorithms.graphtheory.treealgorithms.TreeCenterLongestPathImpl
82+
.findTreeCenters(tree);
83+
84+
assertThat(impl1).containsExactlyElementsIn(impl2);
85+
}
86+
}
87+
}
88+
89+
public static List<List<Integer>> generateRandomTree(int n) {
90+
List<Integer> nodes = new ArrayList<>();
91+
nodes.add(0);
92+
93+
List<List<Integer>> g = createEmptyTree(n);
94+
for (int nextNode = 1; nodes.size() != n; nextNode++) {
95+
int randomNode = nodes.get((int) (Math.random() * nodes.size()));
96+
addUndirectedEdge(g, randomNode, nextNode);
97+
nodes.add(nextNode);
98+
}
99+
return g;
100+
}
77101
}

0 commit comments

Comments
 (0)