Storing rooted trees

image.png

  • 左子树和右子树的节点求法
    • left node: 2*i +1
    • right node: 2*i + 2

      root a tree

      How to find the center node(s) of tree?

      使用剪枝来实现 —- 对叶子结点进行-1

只有一个中心

比如下面的图
image.png

第一次剪枝

image.png
将 上图红色的node,degree 减一 变为如下图
image.png

第二次剪枝

当我们修剪节点时,也会减少节点度值

再次将上图中的红色 的 degree 减一 ,变为如下图 ,这个时候只剩下了2,就为中心node
image.png

两个中心

image.png
红色剪枝
image.png
最后剩下如下图两个node。 1 和 3
image.png

伪代码

image.png

实现

  1. import java.util.ArrayList;
  2. import java.util.LinkedList;
  3. import java.util.List;
  4. public class TreeCenter {
  5. public static List<Integer> findTreeCenters(List<List<Integer>> tree) {
  6. final int n = tree.size();
  7. int[] degree = new int[n];
  8. // Find all leaf nodes
  9. List<Integer> leaves = new ArrayList<>();
  10. for (int i = 0; i < n; i++) {
  11. List<Integer> edges = tree.get(i);
  12. degree[i] = edges.size();
  13. if (degree[i] <= 1) {
  14. leaves.add(i);
  15. degree[i] = 0;
  16. }
  17. }
  18. int processedLeafs = leaves.size();
  19. // Remove leaf nodes and decrease the degree of each node adding new leaf nodes progressively
  20. // until only the centers remain.
  21. while (processedLeafs < n) {
  22. List<Integer> newLeaves = new ArrayList<>();
  23. for (int node : leaves) {
  24. for (int neighbor : tree.get(node)) {
  25. if (--degree[neighbor] == 1) {
  26. newLeaves.add(neighbor);
  27. }
  28. }
  29. degree[node] = 0;
  30. }
  31. processedLeafs += newLeaves.size();
  32. leaves = newLeaves;
  33. }
  34. return leaves;
  35. }
  36. /** ********** TESTING ********* */
  37. // Create an empty tree as a adjacency list.
  38. public static List<List<Integer>> createEmptyTree(int n) {
  39. List<List<Integer>> tree = new ArrayList<>(n);
  40. for (int i = 0; i < n; i++) tree.add(new LinkedList<>());
  41. return tree;
  42. }
  43. public static void addUndirectedEdge(List<List<Integer>> tree, int from, int to) {
  44. tree.get(from).add(to);
  45. tree.get(to).add(from);
  46. }
  47. public static void main(String[] args) {
  48. List<List<Integer>> graph = createEmptyTree(9);
  49. addUndirectedEdge(graph, 0, 1);
  50. addUndirectedEdge(graph, 2, 1);
  51. addUndirectedEdge(graph, 2, 3);
  52. addUndirectedEdge(graph, 3, 4);
  53. addUndirectedEdge(graph, 5, 3);
  54. addUndirectedEdge(graph, 2, 6);
  55. addUndirectedEdge(graph, 6, 7);
  56. addUndirectedEdge(graph, 6, 8);
  57. // Centers are 2
  58. System.out.println(findTreeCenters(graph));
  59. // Centers are 0
  60. List<List<Integer>> graph2 = createEmptyTree(1);
  61. System.out.println(findTreeCenters(graph2));
  62. // Centers are 0,1
  63. List<List<Integer>> graph3 = createEmptyTree(2);
  64. addUndirectedEdge(graph3, 0, 1);
  65. System.out.println(findTreeCenters(graph3));
  66. // Centers are 1
  67. List<List<Integer>> graph4 = createEmptyTree(3);
  68. addUndirectedEdge(graph4, 0, 1);
  69. addUndirectedEdge(graph4, 1, 2);
  70. System.out.println(findTreeCenters(graph4));
  71. // Centers are 1,2
  72. List<List<Integer>> graph5 = createEmptyTree(4);
  73. addUndirectedEdge(graph5, 0, 1);
  74. addUndirectedEdge(graph5, 1, 2);
  75. addUndirectedEdge(graph5, 2, 3);
  76. System.out.println(findTreeCenters(graph5));
  77. // Centers are 2,3
  78. List<List<Integer>> graph6 = createEmptyTree(7);
  79. addUndirectedEdge(graph6, 0, 1);
  80. addUndirectedEdge(graph6, 1, 2);
  81. addUndirectedEdge(graph6, 2, 3);
  82. addUndirectedEdge(graph6, 3, 4);
  83. addUndirectedEdge(graph6, 4, 5);
  84. addUndirectedEdge(graph6, 4, 6);
  85. System.out.println(findTreeCenters(graph6));
  86. }
  87. }

Identifying and encoding isomorphic trees