算法与数据结构(16)—— 二叉树的深度遍历(递归与非递归)与广度遍历

二叉树的深度优先遍历

  • 前序遍历:先访问当前节点,再依次递归访问左右子树
  • 中序遍历:先递归访问左子树,再访问自身,再递归访问右子树
  • 后续遍历:先递归访问左右子树,再访问自身节点

前序:

private void preOrder(Node node){
        if(node == null) return;
        visit(node);
        preOrder(node.left);
        preOrder(node.right);
    }
 private void preOrderByStack(Node p){
        if(p == null) return;
        Stack<Node> stack = new Stack<Node>();
        stack.push(p);
        while(!stack.isEmpty()){
            p = stack.pop();
            visit(p);
            if(p.right != null)
                stack.push(p.right);
            if(p.left != null)
                stack.push(p.left);
        }
    }

中序:

private void inOrderByStack(Node p){
        if(p == null) return;
        Stack<Node> stack = new Stack<Node>();
        while(!stack.isEmpty() || p != null){

            while(p != null){
                stack.push(p);
                p = p.left;
            }

            if(!stack.isEmpty()){
                p = stack.pop();
                visit(p);
                p = p.right;
            }
        }
    }

后序:

  private void postOrderByStack(Node p){
        if(p == null) return;
        Stack<Node> stack = new Stack<Node>();

        Node q = null;

        while(p != null){
            stack.push(p);
            p = p.left;
        }

        while(!stack.isEmpty()){
            p = stack.pop();

            if(p.right != null && p.right != q){
                stack.push(p);
                p = p.right;
                while(p != null){
                    stack.push(p);
                    p = p.left;
                }
            }else {
                visit(p);
                q = p;
            }
        }
    }


广度遍历:

private void levelOrder(Node p){
        if(p == null) return;
        Queue<Node> q = new LinkedList<Node>();
        q.offer(p);
        while(!q.isEmpty()){
            Node node = q.poll();
            visit(node);
            if(node.left != null) q.offer(node.left);
            if(node.right != null) q.offer(node.right);
        }
    }

深度(递归):

private int getDepth(Node node){
       if(node == null) return 0;
       int left = getDepth(node.left);
       int right  = getDepth(node.right);
       return left > right ? left + 1 : right + 1;
    }


广度和深度优先遍历:

两者都很高效为O(n),基本是最小的,因为每个点至少要遍历一次~

之前的快速排序和归并排序,两者的本质上都是二叉树的深度优先遍历过程。

猜你喜欢

转载自blog.csdn.net/jae_wang/article/details/80614385