获取二叉树深度的非递归方式

时间:2014-08-24 01:35:50

标签: java algorithm recursion data-structures binary-tree

我正在尝试使用非递归方式获取二叉树的深度,但下面的代码看起来效果不好,试图调试很多,没有任何线索。请帮忙。感谢。

public int treeDepthNonRecursion(TreeNode root) {
    int max = 0;
    int curSum = 0;
    if(root==null) {
        return 0;
    }

    TreeNode temp = root;
    Stack<TreeNode> stack = new Stack<TreeNode>();
    Stack<Integer> stack2 = new Stack<Integer>();
    stack.push(temp);
    stack2.push(curSum);

    while(!stack.isEmpty()) {
        if(temp!=null)  {
            stack.push(temp);
            stack2.push(curSum++);
            System.out.println("here curSum="+curSum);
            temp = temp.getLeftChild();
        } else {
            temp = stack.pop();
            curSum = stack2.pop();
            if(curSum>max) {
                max = curSum;
            }
            temp = temp.getRightChild();
        }
    }

    return max;
}

2 个答案:

答案 0 :(得分:0)

如果在每个节点中维护父引用,则可以执行非递归,非基于堆栈的遍历。这可以如下所示执行。

public class Tree< E > {

    private class Node {

        public E val = null;

        public Node parent = null;

        public Node right = null;
        public Node left = null;

    }

    private Node root = null;

    public int getDepth() {
        int maxDepth = -1;
        int curDepth = 0;

        Node prev = null;
        Node cur = root;
        while( cur != null ) {
            if( prev == cur.parent ) {
                if( cur.left != null ) {
                    curDepth++;
                    prev = cur;
                    cur = cur.left;

                    continue;
                }

                prev = null;
            }

            if( prev == cur.left ) {
                if( cur.right != null ) {
                    curDepth++;
                    prev = cur;
                    cur = cur.right;

                    continue;
                }

                prev = null;
            }

            if( prev == cur.right ) {
                if( curDepth > maxDepth ) {
                    maxDepth = curDepth;
                }
                curDepth--;

                prev = cur;
                cur = cur.parent;
            }
        }

        return maxDepth;
    }

您可以编辑上述解决方案,以执行树的前,中,后顺序遍历。这确实伴随着每个节点中另一个引用的开销。我最初为家庭作业写了这篇文章,并从记忆中重写了它。我不完全确定它是否100%正确,但是在我的有限测试中起作用。

答案 1 :(得分:0)

发现错误(可能是您正在寻找的错误):

temp = temp.getRightChild();

在此行之前,您有一个节点temp及其相关深度(例如curSum = 2)。在这一行之后,在下一个循环中,temp将是正确的子节点,但关联的深度仍然是父节点之一(按照示例,仍然是curSum = 2)。

您可以在获得合适的孩子后通过增加curSum来修复代码:

temp = temp.getRightChild();
curSum += 1;

您的代码很难理解,您似乎正在以leftChild-&gt; node-&gt; rightChild顺序遍历树。

我建议你有一个更简单的算法,从堆栈弹出的每个节点完全相同的计算。例如:

public static int treeDepthNonRecursion(TreeNode root) {
    int maxDepth = 0;
    int depth = 0;
    if (root == null) {
        return 0;
    }

    TreeNode node = root;
    Stack<TreeNode> nodesStack = new Stack<TreeNode>();
    Stack<Integer> depthStack = new Stack<Integer>();
    nodesStack.push(node);
    depthStack.push(depth);

    while (!nodesStack.isEmpty()) {
        node = nodesStack.pop();
        depth = depthStack.pop();
        maxDepth = Math.max(maxDepth, depth);
        if (node.getLeftChild() != null) {
            nodesStack.push(node.getLeftChild());
            depthStack.push(depth + 1);
        }
        if (node.getRightChild() != null) {
            nodesStack.push(node.getRightChild());
            depthStack.push(depth + 1);
        }
    }

    return maxDepth;
}