Finding max depth of binary tree without recursion

前端 未结 7 900
夕颜
夕颜 2020-12-24 09:23

Recursive mechanism to find max depth of depth of binary tree is very straightforward, but how can we do it efficiently without recursion as I have large tree where I would

相关标签:
7条回答
  • 2020-12-24 09:37

    This variant uses two stacks, one for additional nodes to explore (wq) and one always containing the current path from the root (path). When we see the same node on the top of both stacks it means we've explored everything below it and can pop it. This is the time to update the tree depth too. On random or balanced trees the additional space should be O(log n), in the worst case O(n), of course.

    static int maxDepth (Node r) {
        int depth = 0;
        Stack<Node> wq = new Stack<>();
        Stack<Node> path = new Stack<>();
    
        wq.push (r);
        while (!wq.empty()) {
            r = wq.peek();
            if (!path.empty() && r == path.peek()) {
                if (path.size() > depth)
                    depth = path.size();
                path.pop();
                wq.pop();
            } else {
                path.push(r);
                if (r.right != null)
                    wq.push(r.right);
                if (r.left != null)
                    wq.push(r.left);
            }
        }
    
        return depth;
    }
    

    (Shameless plug: I had this idea for using dual stacks for non-recursive traversals a few weeks ago, check for a C++ code here http://momchil-velikov.blogspot.com/2013/10/non-recursive-tree-traversal.html not that I claim I was the first to invent it :)

    0 讨论(0)
  • 2020-12-24 09:39

    Using a Array to store a layer of nodes, each time find a new layer. the depth plus one.

    public int maxDepth2(TreeNode root){
            if(root == null){
                return 0;
            }
    
            int depth = 0;
    
            ArrayList<TreeNode> oneLayer = new ArrayList<TreeNode>();
            oneLayer.add(root);
    
            while(!oneLayer.isEmpty()){
                ArrayList<TreeNode> newLayer = new ArrayList<TreeNode>();
                for(TreeNode node:oneLayer){
                    if(node.right!=null){
                        newLayer.add(node.right);
                    }
                    if(node.left!=null){
                        newLayer.add(node.left);
                    }
                }
                oneLayer = newLayer;
                depth++;
            }
    
            return depth;
        }
    
    0 讨论(0)
  • 2020-12-24 09:42

    The recursive approach you've described is essentially a DFS over the binary tree. You can implement this iteratively if you'd like by storing an explicit stack of nodes and keeping track of the maximum depth encountered.

    Hope this helps!

    0 讨论(0)
  • 2020-12-24 09:42

    I have written following logic to do find max and min depth which doesn't involve recursion and without increasing the space complexity.

    // Find the maximum depth in the tree without using recursion
    private static int maxDepthNoRecursion(TreeNode root) {
        return Math.max(maxDepthNoRecursion(root, true), maxDepthNoRecursion(root, false)); 
    }
    
    // Find the minimum depth in the tree without using recursion
    private static int minDepthNoRecursion(TreeNode root) {
        return Math.min(maxDepthNoRecursion(root, true), maxDepthNoRecursion(root, false)); 
    }
    
    private static int maxDepthNoRecursion(TreeNode root, boolean left) {
        Stack<TreeNode> stack = new Stack<>();
        stack.add(root);
        int depth = 0;
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if (left && node.left != null) stack.add(node.left);
            // Add the right node only if the left node is empty to find max depth
            if (left && node.left == null && node.right != null) stack.add(node.right); 
            if (!left && node.right != null) stack.add(node.right);
            // Add the left node only if the right node is empty to find max depth
            if (!left && node.right == null && node.left != null) stack.add(node.left);
            depth++;
        }
        return depth;
    }
    
    0 讨论(0)
  • 2020-12-24 09:42

    If you can maintain left and right values at each node, it can be done.

    http://leetcode.com/2010/04/maximum-height-of-binary-tree.html.

    Possible duplicate: Retrieving a Binary-Tree node's depth non-recursively

    0 讨论(0)
  • 2020-12-24 09:45

    Here is a BFS solution:

    private class NodeHeight
    {
        public Node node;
        public int height;
    
        public NodeHeight(Node n, int height)
        {
            node = n;
            this.height = height;
        }
    }
    
    public int GetHeightBfs(Node root)
    {
        if(root == null)
            return 0;
        else
            return GetHeightBfs(new NodeHeight(root, 1))
    }
    
    private int GetHeightBfs(NodeHeight root)
    {   
        int maxHeight = int.Min;
        int minHeight = int.Max;
        var q = new Queue<Node>();
        q.Enqueue(root);
        while(q.length > 0)
        {       
            var nodeHeight = q.Dequeue();
            var node = nodeHeight.node;
            int height = nodeHeight.height;
            if(node.left == null && node.right == null)
            {
                maxHeight = Math.max(maxHeight, height);
                minHeight = Math.min(minHeight, height);
            }
    
            if(node.left != null)
                q.Enqueue(new NodeHeight(node.left, height + 1);
    
            if(node.right != null)
                q.Enqueue(new NodeHeight(node.right, height + 1);
        }
    
        return maxHeight;
    }   
    

    Note that you can also return minHeight. To make it DFS just replace Queue with Stack.

    0 讨论(0)
提交回复
热议问题