二叉树的三种遍历递归与非递归实现

public class Main8 {
	/*
           1
          2 3
         4 5 6 7
        8 9
	*/
    public static void main(String[] args) {
        Node root = createTwoTree();
        // 前序遍历
        preSort(root);
        System.out.println("==========前序遍历===========");
        preSort2(root);
        System.out.println("==========前序遍历===========");


        // 中序遍历
        inSort(root);
        System.out.println("==========中序遍历===========");
        inSort2(root);
        System.out.println("==========中序遍历===========");

        // 后序遍历
        endSort(root);
        System.out.println("==========后序遍历===========");
        endSort2(root);
        System.out.println("==========后序遍历===========");
    }

    /**
     * 构建二叉树
     * @return
     */
    public static Node createTwoTree(){
        Node node1 = new Node(1);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        Node node4 = new Node(4);
        Node node5 = new Node(5);
        Node node6 = new Node(6);
        Node node7 = new Node(7);
        Node node8 = new Node(8);
        Node node9 = new Node(9);

        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        node3.left = node6;
        node3.right = node7;
        node4.left = node8;
        node4.right = node9;

        node5.left = null;
        node5.right = null;
        node6.left = null;
        node6.right = null;
        node7.left = null;
        node7.right = null;

        node8.left = null;
        node8.right = null;
        node9.left = null;
        node9.right = null;

        return node1;
    }


    /**
     * 先序遍历
     * @param root
     */
    public static void preSort(Node root){
        if(root != null){
            System.out.print(root.data + " ");
            preSort(root.left);
            preSort(root.right);
        }
    }

    public static void preSort2(Node root){
        Stack<Node> st = new Stack<>();
        Node curr = root;
        while(curr != null || !st.isEmpty()){
            while(curr != null){
                System.out.print(curr.data + " ");
                st.push(curr);
                curr = curr.left;
            }
            Node top = st.pop();
            curr = top.right;
        }
    }
    
    private static void prePrint(Node root) {
        // 遍历顺序:头 -》 左 -》 右
        // 压栈顺序:头 -》 右 -》 左
        /**
         * 步骤:
         * 1.头结点首先入栈
         * 2.弹出栈顶元素
         * 3.右节点入栈
         * 4.左节点入栈
         * 5.重复1,2,3,4,直到栈为空
         */

        Stack<Node> st = new Stack<>();
        st.add(root);
        while(!st.isEmpty()){
            Node node = st.pop();
            System.out.print(node.data+" ");

            if(node.right != null){
                st.add(node.right);
            }
            if(node.left != null){
                st.add(node.left);
            }
        }
        System.out.println();
    }


    /**
     * 中序遍历
     * @param root
     */
    public static void inSort(Node root){
        if(root != null){
            inSort(root.left);
            System.out.print(root.data + " ");
            inSort(root.right);
        }
    }

    public static void inSort2(Node root){
        Stack<Node> st = new Stack<>();
        Node curr = root;
        while(curr != null || !st.isEmpty()){
            while(curr != null){
                st.push(curr);
                curr = curr.left;
            }
            Node top = st.pop();
            System.out.print(top.data + " ");
            curr = top.right;
        }
    }
    
    private static void inPrint(Node root) {
        // 遍历顺序:左 -》 头 -》 右
        /**
         * 步骤:
         * 1.将当前节点的左子树全部入栈
         * 2.弹出栈顶节点,打印
         * 3.将栈顶元素的右节点作为当前节点
         * 4.重复1,2,3步骤
         */
        Stack<Node> st = new Stack<>();
        Node head = root;
        while(!st.isEmpty() || head != null){
            while(head != null){
                st.add(head);
                head = head.left;
            }

            Node node = st.pop();
            System.out.print(node.data + " ");
            head = node.right;
        }
        System.out.println();
    }



    /**
     * 后续遍历
     * @param root
     */
    public static void endSort(Node root){
        if(root != null){
            endSort(root.left);
            endSort(root.right);
            System.out.print(root.data + " ");
        }
    }

    public static void endSort2(Node root){
        Stack<Node> st = new Stack<>();
        Node curr = root;
        Node pre = null;
        while(curr != null || !st.isEmpty()){
            while(curr != null){
                st.push(curr);
                curr = curr.left;
            }
            Node top = st.peek();
            // 如果右子树不存在 或者 右子树存在,但是已经被访问过
            if(top.right == null || top.right == pre){
                System.out.print(top.data + " ");
                // 记录被访问过
                pre = top;
                //出栈
                st.pop();
            }else{
                // 右子树没有被访问过,则访问
                curr = top.right;
            }
        }
    }

	private static void posPrint(Node root) {
        // 遍历顺序:左 -》 右 -》 头
        // st栈: 压栈顺序:头 -》 左 -》 右, 出栈顺序:头 -》 右 -》 左, 将出栈的元素压入辅助栈中
        Stack<Node> st = new Stack<>();
        // 辅助栈:辅助栈出栈的顺序为:左 -》 右 -》 头,就是后续遍历的顺序
        Stack<Node> assistStack = new Stack<>();

        st.add(root);
        while(!st.isEmpty()){
            Node node = st.pop();
            assistStack.add(node);
            if(node.left != null){
                st.add(node.left);
            }
            if(node.right != null){
                st.add(node.right);
            }
        }

        while(!assistStack.isEmpty()){
            System.out.print(assistStack.pop().data + " ");
        }
        System.out.println();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值