Skip to content

Commit 3d2904a

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

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
3+
4+
javac -d src/main/java src/main/java/com/williamfiset/algorithms/graphtheory/treealgorithms/TreeCenterLongestPathImpl.java
5+
6+
java -cp src/main/java com/williamfiset/algorithms/graphtheory/treealgorithms/TreeCenterLongestPathImpl
7+
8+
9+
*/
10+
11+
package com.williamfiset.algorithms.graphtheory.treealgorithms;
12+
13+
import java.util.*;
14+
15+
public class TreeCenterLongestPathImpl {
16+
17+
private static int[] dfs(List<List<Integer>> graph, boolean[] visited, int[] prev, int at, int parent) {
18+
19+
// Already visited this node
20+
if (visited[at]) return new int[] {0, parent};
21+
22+
// Visit this node
23+
visited[at] = true;
24+
25+
// Remember where we came from to rebuild path later on.
26+
prev[at] = parent;
27+
28+
int bestDist = 0, index = -1;
29+
List<Integer> edges = graph.get(at);
30+
31+
for (int to : edges) {
32+
int[] tuple = dfs(graph, visited, prev, to, at);
33+
int dist = tuple[0] + 1;
34+
if (dist > bestDist) {
35+
bestDist = dist;
36+
index = tuple[1];
37+
}
38+
}
39+
40+
return new int[] {bestDist, index};
41+
}
42+
43+
public static List<Integer> treeCenter(List<List<Integer>> graph) {
44+
List<Integer> centers = new ArrayList<>();
45+
if (graph == null) return centers;
46+
47+
int n = graph.size();
48+
boolean[] visited = new boolean[n];
49+
50+
// Do DFS to find furthest node from the start
51+
int furthestIndex = dfs(graph, visited, new int[n], 0, -1)[1];
52+
53+
// Singleton
54+
if (furthestIndex == -1) {
55+
centers.add(0);
56+
return centers;
57+
}
58+
59+
// Do another DFS, but this time from the furthest
60+
// node and record the distance to that node.
61+
Arrays.fill(visited, false);
62+
int[] prev = new int[n];
63+
int newfurthestIndex = dfs(graph, visited, prev, furthestIndex, -1)[1];
64+
65+
List<Integer> path = new LinkedList<>();
66+
for (int i = newfurthestIndex; i != -1; i = prev[i]) {
67+
path.add(i);
68+
}
69+
70+
if (path.size() % 2 == 0) {
71+
centers.add(path.get(path.size()/2-1));
72+
}
73+
centers.add(path.get(path.size()/2));
74+
return centers;
75+
}
76+
77+
/** ********** TESTING ********* */
78+
79+
// Create an empty tree as a adjacency list.
80+
public static List<List<Integer>> createEmptyTree(int n) {
81+
List<List<Integer>> tree = new ArrayList<>(n);
82+
for (int i = 0; i < n; i++) tree.add(new LinkedList<>());
83+
return tree;
84+
}
85+
86+
public static void addUndirectedEdge(List<List<Integer>> tree, int from, int to) {
87+
tree.get(from).add(to);
88+
tree.get(to).add(from);
89+
}
90+
91+
public static void main(String[] args) {
92+
93+
List<List<Integer>> graph = createEmptyTree(9);
94+
addUndirectedEdge(graph, 0, 1);
95+
addUndirectedEdge(graph, 2, 1);
96+
addUndirectedEdge(graph, 2, 3);
97+
addUndirectedEdge(graph, 3, 4);
98+
addUndirectedEdge(graph, 5, 3);
99+
addUndirectedEdge(graph, 2, 6);
100+
addUndirectedEdge(graph, 6, 7);
101+
addUndirectedEdge(graph, 6, 8);
102+
103+
// Centers are 2
104+
System.out.println(treeCenter(graph)+"\n");
105+
106+
// Centers are 0
107+
List<List<Integer>> graph2 = createEmptyTree(1);
108+
System.out.println(treeCenter(graph2)+"\n");
109+
110+
// Centers are 0,1
111+
List<List<Integer>> graph3 = createEmptyTree(2);
112+
addUndirectedEdge(graph3, 0, 1);
113+
System.out.println(treeCenter(graph3)+"\n");
114+
115+
// Centers are 1
116+
List<List<Integer>> graph4 = createEmptyTree(3);
117+
addUndirectedEdge(graph4, 0, 1);
118+
addUndirectedEdge(graph4, 1, 2);
119+
System.out.println(treeCenter(graph4)+"\n");
120+
121+
// Centers are 1,2
122+
List<List<Integer>> graph5 = createEmptyTree(4);
123+
addUndirectedEdge(graph5, 0, 1);
124+
addUndirectedEdge(graph5, 1, 2);
125+
addUndirectedEdge(graph5, 2, 3);
126+
System.out.println(treeCenter(graph5)+"\n");
127+
128+
// Centers are 2,3
129+
List<List<Integer>> graph6 = createEmptyTree(7);
130+
addUndirectedEdge(graph6, 0, 1);
131+
addUndirectedEdge(graph6, 1, 2);
132+
addUndirectedEdge(graph6, 2, 3);
133+
addUndirectedEdge(graph6, 3, 4);
134+
addUndirectedEdge(graph6, 4, 5);
135+
addUndirectedEdge(graph6, 4, 6);
136+
System.out.println(treeCenter(graph6)+"\n");
137+
}
138+
}

0 commit comments

Comments
 (0)