【问题标题】:Construct a tree from a given array从给定的数组构造一棵树
【发布时间】:2018-07-13 09:38:37
【问题描述】:

我想从给定的数组和根节点构造一个图,节点如下所述,

static class TreeNode {

    private int value;
    private ArrayList<TreeNode> children; 

    public TreeNode(int nodeValue) {
        this.value = nodeValue;
        this.children = new ArrayList<TreeNode>();
    }

    public int getValue() {
        return this.value;
    }

    public void addChild(TreeNode child) {
        this.children.add(child);
    }

    public ArrayList<TreeNode> getChildren() {
        return this.children;
    } 
} 

下面提供的用于构造图形的数组,

T[0] = 1
T[1] = 2
T[2] = 3
T[3] = 3
T[4] = 2
T[5] = 1
T[6] = 4

数组T描述了一个城市网络,如果T[P] = Q且P≠Q,那么城市P和Q之间有一条直达路。如果2的索引是根,那么下图是,

     2 - 3
    / \
   1   4
  / |  |
 0  5  6

显然,我可以为给定的数组手动完成,

    final int N = 7;
    TreeNode[] nodes = new TreeNode[N];

    for (int i = 0; i < N; i++) {
        nodes[i] = new TreeNode(i);
    }


    TreeNode root = nodes[2];

    root.addChild(nodes[1]);
    root.addChild(nodes[3]);
    root.addChild(nodes[4]);


    nodes[1].addChild(nodes[0]);
    nodes[1].addChild(nodes[5]);

    nodes[4].addChild(nodes[6]);

当我给定一个数组和 K 值后,如何以编程方式构造?请帮忙。

【问题讨论】:

  • 你试过什么?
  • @nicomp 我仍在尝试正确编写它。完成后我会在这里更新
  • @nicomp 我试过并提供了答案

标签: java algorithm graph tree


【解决方案1】:

构造TreeNode[]数组后,就很简单了:

TreeNode root = null;
for (int i=0; i<T.length; ++i) {
    if (T[i] == i) { // if it's a root node
        //TODO: Test for multiple root nodes here
        root = nodes[i];
    } else {
        nodes[T[i]].addChild(nodes[i]);
    }
}

我将在TreeNode 类中添加一个private TreeNode parent; 对象,将其初始化为null,并将其设置为addChild 方法中的父引用。即使您在第一次使用此类时不需要它,在调试期间也很方便。也许你以后会需要它。

【讨论】:

  • 我愿意接受你的回答,但输出并不完全正确。我运行代码并得到:The root = 3 Parent 3 has children = 2 Parent 2 has children = 1 Parent 2 has children = 4 Parent 1 has children = 0 Parent 1 has children = 5 Parent 4 has children = 6 根是 2,父 3 有子 = 2 不正确,实际上相反是真的
  • @Arefe 这与您提供的数据并不相符。 T[2] = 3 说 3 是 2 的父级,所以 2 不能是根。而T[3] = 3 表明 3 没有父级,所以它是一个根。是否有一些额外的规则和参数使 2 成为根?如果是这样,如果 3 真的是树的一部分,例如。 T[3] = 7; T[7] = 8; T[8] = 8; T[9] = 8; T[10] = 9; 等等...?
  • 是的,根索引K 提供了您需要开始的位置。所以,即使 T[children] = parent,如果 T[K] = V 那么 K 是 V 的 parent。我现在如何更改代码
【解决方案2】:

遍历所有节点, 为每个节点获取节点的值并将当前节点添加到该节点的值。

for (int i = 0; i < N; i++) {
    nodes[nodes[i].getValue()].addChild(nodes[i])
}

【讨论】:

    【解决方案3】:

    我写了一个答案,但是,它并没有显示所有的孩子。代码如下,

    public class App {
    
        static class TreeNode {
    
            private int value;
            private ArrayList<TreeNode> children;
    
            public TreeNode(int nodeValue) {
                this.value = nodeValue;
                this.children = new ArrayList<TreeNode>();
            }
    
            public int getValue() {
                return this.value;
            }
    
            public void addChild(TreeNode child) {
                this.children.add(child);
            }
    
            public ArrayList<TreeNode> getChildren() {
                return this.children;
            }
        }
    
    
        public static TreeNode buildGraph(int[] T, int K) {
    
            final int N = T.length;
    
            TreeNode[] nodes = new TreeNode[N];
    
            for (int i = 0; i < N; i++) {
                nodes[i] = new TreeNode(i);
            }
    
            /*
                T[0] = 1
                T[1] = 2
                T[2] = 3
                T[3] = 3
                T[4] = 2
                T[5] = 1
                T[6] = 4
    
                     2 - 3
                    / \
                   1   4
                  / |  |
                 0  5  6
            * */
    
            TreeNode root = nodes[K];
    
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
    
            boolean[] visited = new boolean[N];
    
            while (!queue.isEmpty()) {
    
                TreeNode node = queue.poll();
                int index = node.getValue();
    
                visited[index] = true;
    
                // T[3] = 3 is a leaf with no further connection to develop
                if (index == T[index]) {
                    continue;
                }
    
                // 2 != 3 for the root node and we havent visited node 3 earlier
                if (index != T[index] && !visited[T[index]]) {
    
                    node.addChild(nodes[T[index]]);
                    queue.offer(nodes[T[index]]);
                }
    
                int left = 0, right = N - 1;
    
                while (left < index && right > index) {
    
                    if (T[left] == index) {
    
                        node.addChild(nodes[left]);
                        queue.offer(nodes[left]);
                    }
    
                    if (T[right] == index) {
    
                        node.addChild(nodes[right]);
                        queue.offer(nodes[right]);
                    }
    
                    left++;
                    right--;
                }
            }
    
            return root;
        }
    
        public static void main(String[] args) {
    
            int[] T = new int[7];
    
            T[0] = 1;
            T[1] = 2;
            T[2] = 3;
            T[3] = 3;
            T[4] = 2;
            T[5] = 1;
            T[6] = 4;
    
            TreeNode root = buildGraph(T, 2);
    
            System.out.println("The root = " + root.getValue());
    
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
    
            while(!queue.isEmpty()){
    
                TreeNode node = queue.poll();
    
                ArrayList<TreeNode> children = node.getChildren();
    
                for (int i = 0; i < children.size(); i++) {
    
                    TreeNode child = children.get(i);
                    queue.offer(child);
    
                    System.out.println("Parent "+ node.getValue()+ " has children = "+ child.getValue());
                }
            }
        }
    }
    

    在我运行的时候,我会得到类似的输出,

    The root = 2
    Parent 2 has children = 3
    Parent 2 has children = 1
    Parent 1 has children = 0
    

    谁能帮我纠正我怎么想念其他孩子?

    更新

    我是根据另一个似乎更简单的答案来写的。

    public static TreeNode buildGraph1(int[] T, int K) {
    
            final int N = T.length;
    
            TreeNode[] nodes = new TreeNode[N];
    
            for (int i = 0; i < N; i++) {
                nodes[i] = new TreeNode(i);
            }
    
            /*
           T[children] = parent if the children != K
    
                T[0] = 1
                T[1] = 2
                T[2] = 3
                T[3] = 3
                T[4] = 2
                T[5] = 1
                T[6] = 4
    
                     2 - 3
                    / \
                   1   4
                  / |  |
                 0  5  6
            * */
    
            TreeNode root = nodes[K];
            int value = root.getValue();
    
            if (T[K] != K) {
                nodes[K].addChild(nodes[T[K]]);
            }
    
            for (int i = 0; i < T.length; ++i) {
    
                if (K == i) {
                    continue;
                }
    
                if (T[i] != i) {
                    nodes[T[i]].addChild(nodes[i]);
                }
            }
    
            return root;
        }
    

    输出如下:

    The root = 2
    Parent 2 has children = 3
    Parent 2 has children = 1
    Parent 2 has children = 4
    
    
    
    
    Parent 1 has children = 0
    Parent 1 has children = 5
    
    
    Parent 4 has children = 6
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 2021-08-06
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多