zoukankan      html  css  js  c++  java
  • 二叉树的遍历

    定义二叉树

    public class Node {
        int value;
        Node left;
        Node right;
        Node(int data){
            this.value = data;
        }
    }
    
    

    1. 递归方式实现二叉树的先序遍历

    public void preOrderRecur(Node node){
        if (node == null){
            return;
        }
        System.out.print(node.value+ " ");
        preOrderRecur(node.left);
        preOrderRecur(node.right);
    }
    

    2. 非递归方式实现二叉树的先序遍历

    具体过程

    • 首先申请一个新的栈,记为stack。
    • 然后将头节点head压入stack中。
    • 每次从stack中弹出栈顶节点,记为cur,然后打印cur节点的值。如果cur右孩子不为空的话,将cur的右孩子先压入stack中。最后如果cur的左孩子不为空的话,将cur的左孩子压入stack中。
    • 不断重复步骤3,直到stack为空,全部过程结束。
    public void preOrderTraverse(Node node) {
        if (node == null)
            return;
        Stack<Node> stack = new Stack<>();
        stack.push(node);
        while (!stack.empty()) {
            node = stack.pop();
            System.out.print(node.value + " ");
            if (node.right != null)
                stack.push(node.right);
            if (node.left != null)
                stack.push(node.left);
        }
    }
    

    3.递归方式实现二叉树的中序遍历

    public void inOrderRecur(Node node){
        if (node == null)
            return;
        inOrderRecur(node.left);
        System.out.print(node.value+" ");
        inOrderRecur(node.right);
    }
    

    4.非递归方式实现二叉树的中序遍历

    具体过程

    • 申请一个新的栈,记为stack,申请一个变量cur,初始化时令cur等于头节点。
    • 先把cur节点压入栈中,对已cur节点为头的整颗子树来说,依次把整颗树的左边界压入栈中,即不断令cur = cur.left,然后重复步骤2。
    • 不断重复步骤2,直到发现cur为空,此时从stack中弹出一个节点,记为node。打印node的值,并让cur = node.right,然后继续重复步骤2。
    • 当stack为空并且cur为空时,整个过程结束。
    public void inOrderTraverse(Node node) {
        if (node == null)
            return;
        Stack<Node> stack = new Stack<>();
        Node cur = node;
        while (!stack.empty()||cur !=null) {
            if (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }else {
                node = stack.pop();
                System.out.print(node.value+" ");
                cur = node.right;
            }
        }
    }
    

    5.递归方法实现二叉树的后续遍历

    public void posOrderRecur(Node node) {
        if (node == null) {
            return;
        }
        posOrderRecur(node.left);
        posOrderRecur(node.right);
        System.out.print(node.value+" ");
    }
    

    6.非递归方法实现二叉树的后序遍历01

    方法一:使用两个栈

    具体过程如下

    • 申请一个栈,记为s1,然后将头节点压入s1中。
    • 从s1中弹出的节点记为cur,然后把cur的左孩子压入s1中,然后把cur的右孩子压入s1中。
    • 在整个过程中,每一个从s1中弹的节点都放进第二个栈s2中。
    • 不断重复步骤2和步骤3,直到s1为空,过程停止。
    • 从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序了。
    public void posOrderTraverse(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> s1 = new Stack<>();
        Stack<Node> s2 = new Stack<>();
        Node cur;
        s1.push(node);
        while (!s1.empty()) {
                cur = s1.pop();
                s2.push(cur);
                if (cur.left != null)
                    s1.push(cur.left);
                if (cur.right != null)
                    s1.push(cur.right);
        }
        while (!s2.empty()) {
            System.out.print(s2.pop().value+" ");
        }
    }
    

    7.非递归方法实现二叉树的后序遍历02

    方法二:使用一个栈实现

    具体过程如下

    • 申请一个栈,记为stack,将头节点压入stack,同时设置两个变量h和c。在整个流程中,h代表最近一次弹出并打印的节点,c代表当前stack的栈顶节点,初始时令h为头节点,c为null。

    • 每次令c等于当前stack的栈顶节点,但是不从stack中弹出节点,此时分为一下三种情况。

      • 如果c的左孩子不为空,并且h不等于c的左孩子,也不等于c的右孩子,则把c的左孩子压入stack中。
      • 如果情况1不成立,并且c的右孩子不为空,并且h不等于c的右孩子,则把c的右孩子压入stack中。
      • 如果情况1和情况2都不成立,那么从stack中弹出c并打印,然后令h等于c。
    public void posOrderTraverse(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        Node h = node;
        Node c = null;
        stack.push(node);
        while (!stack.empty()) {
            c = stack.peek();
            if (c.left != null && h != c.left && h != c.right) {
                stack.push(c.left);
            } else if (c.right != null && h != c.right) {
                stack.push(c.right);
            } else {
                c = stack.pop();
                System.out.print(c.value + " ");
                h = c;
            }
        }
    }
    

    后学末进,才疏学浅,如有疏误,还望不吝赐教。

  • 相关阅读:
    2020/10/10周总结
    2020/10/02周总结
    2020/9/28周总结
    第十二周总结
    第十一周总结
    人月神话阅读笔记03
    人月神话阅读笔记02
    人月神话阅读笔记01
    冲刺一8
    冲刺一7
  • 原文地址:https://www.cnblogs.com/ifreeky/p/7663544.html
Copyright © 2011-2022 走看看