树没有任何父指针。 如果这是图并且目标是10并且k是2,那么输出应该是150,160,8,14。 http://www.geeksforgeeks.org/print-nodes-distance-k-given-node-binary-tree/有一个解决方案,虽然我无法理解它。
所以我根据第一个答案从树中构建了一个无向图。
我认为printN
的复杂性不是O(n)。任何人都可以检查一下。
谢谢!
public class Nth {
private int targetV;
private class Node {
private int data;
private Node left, right;
public Node() {
}
public Node(int data) {
this.data = data;
}
}
private class GraphNode {
private HashMap<Integer, ArrayList<Integer>> edgeMap;
GraphNode() {
edgeMap = new HashMap<>();
}
private void addEdge(int v, int w) {
if (edgeMap.containsKey(v)) {
if (!edgeMap.get(v).contains(w))
edgeMap.get(v).add(w);
} else {
edgeMap.put(v, new ArrayList<>());
edgeMap.get(v).add(w);
}
}
}
public static void main(String[] args) {
new Nth().job1();
}
private void job1() {
Node root = new Node(20);
root.left = new Node(8);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.left.left = new Node(50);
root.left.right.left.left.left = new Node(150);
root.left.right.left.left.left.left = new Node(1250);
root.left.right.left.left.left.right = new Node(12512);
root.left.right.left.left.right = new Node(160);
root.left.right.left.right = new Node(60);
root.left.right.right = new Node(14);
root.right = new Node(22);
GraphNode graphNode = new GraphNode();
generateGraph(null, null, root, graphNode, 10);
check(graphNode);
// printN(graphNode, 2);
}
private void printN(GraphNode graphNode, int k) {
Set<Integer> items = new HashSet<>();
Queue<Integer> queue = new ArrayDeque<>();
queue.add(targetV);
HashMap<Integer, Boolean> hashMap = new HashMap<>();
hashMap.put(targetV, true);
for (int e = 0; e < k; e++) {
items.clear();
Queue<Integer> back = new ArrayDeque<>();
back.addAll(queue);
int xq = back.size();
queue.clear();
for (int i = 0; i < xq; i++) {
int polled = back.poll();
ArrayList<Integer> list = graphNode.edgeMap.get(polled);
list.forEach((x) -> {
if (!hashMap.containsKey(x)) {
queue.add(x);
hashMap.put(x, true);
}
});
}
items.addAll(queue);
}
System.out.println(Arrays.toString(items.toArray()));
}
private void check(GraphNode graphNode) {
for (Map.Entry<Integer, ArrayList<Integer>> pop : graphNode.edgeMap.entrySet()) {
System.out.println(pop.getKey() + "\t\t\t" + Arrays.toString(pop.getValue().toArray()));
}
}
private void generateGraph(Node parent, Node root, Node child, GraphNode graphNode, int target) {
if (child == null && root != null && parent != null)
graphNode.addEdge(root.data, parent.data);
if (child == null) return;
if (root != null) graphNode.addEdge(root.data, child.data);
if (parent != null && root != null) graphNode.addEdge(root.data, parent.data);
if (child.data == target) targetV = child.data;
generateGraph(root, child, child.left, graphNode, target);
generateGraph(root, child, child.right, graphNode, target);
}
}
我的检查乐趣打印:
160 [50]
1250 [150]
1251 [150]
4 [8]
8 [4, 20, 12]
10 [50, 12, 60]
12 [10, 8, 14]
14 [12]
50 [150, 10, 160]
20 [8, 22]
150 [1250, 50, 1251]
22 [20]
60 [10]
答案 0 :(得分:2)
不要把它看成一棵树。将其视为通常连接的双向图并从选定的顶点开始BFS。在BFS搜索的第k步/深度跟踪所有唯一顶点。
答案 1 :(得分:1)
您目前正在尝试理解的链接中给出的算法分为两部分:
k
目标节点的所有子项k
的其他节点(即非子节点)我相信你明白如何解决1,这可以通过目标节点的BFS轻松完成。
然而,您对如何解决2的理解是不正确的。
从树的根开始,当我们遍历树以找到目标节点时,跟踪目标节点的所有祖先(包括根)。
然后:
k-1
的所有节点。k-2
的所有节点。k-3
的所有节点。k
足够大,以便需要这样做。从祖先执行BFS时,您需要注意不要遍历到目标节点。
最后,我想补充一点,更简单的算法是: