Java - 将树转换为具有相同深度的节点列表

时间:2016-10-27 04:21:58

标签: java binary-tree

我正在尝试编写一个代码来将二叉树转换为具有相同深度的节点列表。如果树具有深度d,则将创建d列表。逻辑是按顺序遍历并将当前遍历的节点添加到适当深度的列表中。

public void treeToListofNodesByLevel(Node<T> n,int depth, ArrayList<LinkedList<Node<T>>> treeList){

        if(n.right != null){
            inOrderWithHeight(n.right, depth + 1);
        }
        if(treeList.size() >= depth){
            treeList.add(depth, new LinkedList<Node<T>>() );
        }
        treeList.get(depth).add(n);
        if(n.left != null){
            inOrderWithHeight(n.left, depth + 1);
        }

    }

然后致电:

ArrayList<LinkedList<Node<T>>> result = new ArrayList<LinkedList<Node<T>>>();
treeToListofNodesByLevel(root, 0, result);

这会有用吗?有没有我不处理的角落案件? 此外,现在我传递方法返回的List列表,因为我无法想到在方法中初始化它并在当时返回它同时保持递归结构的方法。有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

我无法理解方法&#34; inOrderWithHeight&#34;是在做。我为这个问题(未优化)做的是使用两个队列遍历BFS,并且每次迭代将该深度的节点添加到该迭代的列表中(每次迭代遍历树的一个深度)。这是我在你的答案中为二叉树做的代码:

Queue<Node<T>> queue1 = new LinkedList<Node<T>>() ;
Queue<Node<T>> queue2 = new LinkedList<Node<T>>() ;
public void treeToListofNodesByLevel(Node<T> root, ArrayList<LinkedList<Node<T>>> treeList) {
    if (root == null)
        return;
    int curr_depth = 0;
    queue1.add(root);
    while(!queue1.isEmpty()){
        treeList.add(curr_depth, new LinkedList<Node<T>>());
        while(!queue1.isEmpty()){
            Node<T> node = queue1.remove();
            treeList.get(curr_depth).add(node);
            if(node.left != null) queue2.add(node.left);
            if(node.right != null) queue2.add(node.right);
        }
        curr_depth++;
        while(!queue2.isEmpty()){
            Node<T> node = queue2.remove();
            queue1.add(node);
        }    
    }
}

我在没有语法检查的情况下动态编写了这个,可能有编译器错误。但希望你明白了。

答案 1 :(得分:1)

你的一般概念非常完美。它会起作用,应该处理所有情况。

但是,您在细节中有一些错误:

  • 检查何时添加新列表时,方向比较错误。它应该是if (treeList.size() <= depth)
  • 每次拨打inOrderWithHeight()(您还没有提供任何代码)都应该是treeToListofNodesByLevel()的递归通话。保持前两个参数不变,只需将treeList传递给第三个参数。
  • 这更像是一个样式问题,但参数类型通常应该被声明为满足您实际需要的最高级别类型。此处无需指定ArrayListLinkedList,任何List都可以。将treeList参数的类型更改为List<List<Node<T>>>

对于在方法内初始化List同时也使用递归的问题,这就是实现辅助方法的用途。取当前treeToListofNodesByLevel的主体并将其移动到私有方法(递归调用已更改,以便私有方法调用自身),让我们将其称为treeToListofNodesByLevelHelper。然后将当前的公共方法更改为:

public List<List<Node<T>>> treeToListofNodesByLevel(Node<T> node) {
    List<List<Node<T>>> result = new ArrayList<>();
    treeToListofNodesByLevelHelper(node, 0, result);
    return result;
}

答案 2 :(得分:0)

为什么你只使用相同的功能,代码会更漂亮:

    public void treeToListofNodesByLevel(BinaryTree node, int currentDepth, List<List<BinaryTree>> result){

    // Check if the list for the currentDepth is created
    if(result.get(currentDepth) != null){
        result.add(currentDepth, new ArrayList<BinaryTree>())
    }

    // Add the current node to the list
    result.get(currentDepth).add(node);


    // Recursive the left node
    if(node.left != null){
        treeToListofNodesByLevel(node.left, currentDepth+1, result);
    } 

    // Recursive the right node
    if(node.right != null){
        treeToListofNodesByLevel(node.right, currentDepth+1, result);
    }
}

在你的主要功能中:

List<List<BinaryTree>> result = new ArrayList<>();
BinaryTree root = new BinaryTree();  
treeToListofNodesByLevel(root, 0, result);