手动创建一棵二叉树,然后利用前序、中序、后序、层序进行遍历(从创建二叉树到各种方式遍历)(含运行结果)

手动创建一棵二叉树,然后利用前序、中序、后序、层序进行遍历

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;

public class BinaryTree {

    private static class Node{
        int val;
        Node left;
        Node right;
        Node(int newVal){
            val = newVal;
        }
    }

    //前序遍历(递归)
    public static void preOrder(Node node){
        if(node == null){
            return;
        }

        System.out.print(node.val + " ");
        preOrder(node.left);
        preOrder(node.right);

    }

    //前序遍历(非递归)
    //主要的思路:利用栈保存未打印的结点,然后逐个出栈处理,在此过程中更新栈

    public static void preOrderUnRec(Node node){
        Stack<Node> stack = new Stack<>();
        stack.push(node);
        Node temp;
        while(!stack.isEmpty()){
            temp = stack.pop();
            if(temp != null){  // root == null时,只会空转一个循环,因此无需判断
                System.out.print(temp.val + " ");
                stack.push(temp.right);//注意:这里的入栈顺序先是right后left
                stack.push(temp.left);// 以保证从栈中取出时为先left后right
            }
        }
    }

    //中序遍历
    public static void inOrder(Node node){
        if(node == null){
            return;
        }

        inOrder(node.left);
        System.out.print(node.val + " ");
        inOrder(node.right);
    }

    //中序遍历(非递归)
    public static void inOrderUnRec(Node node){
        Stack<Node> stack = new Stack<>();
        Node cur = node;
        while(cur != null || !stack.isEmpty()){  //当root==null时,不会进入循环,因此无需判断
            while(cur != null){  //当前结点开始,从上到下将最左边的那一列结点入栈
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();   //取出栈顶的结点(该节点左节点为null,因此现在改打印它)
            System.out.print(cur.val + " ");
            cur = cur.right;  //定位到已打印的结点的右子结点
        }

    }

    //后序遍历
    public static void postOrder(Node node){
        if(node == null){
            return;
        }
        postOrder(node.left);
        postOrder(node.right);
        System.out.print(node.val + " ");
    }

    //后序遍历(非递归)
    //主要思路:利用栈保存未打印的结点,然后逐个出栈,进行判断,并根据需要更新栈
    //        因为处理完左右子树后,再处理根(回溯),所以需要一个记录上一个被打印的结点的引用
    public static void postOrderUnRec(Node node){
        if(node == null){
            return;
        }
        Stack<Node> stack = new Stack<>();
        stack.push(node);
        //cur:当前结点   pre:上一个被打印的结点
        Node cur, pre = null;
        while(!stack.isEmpty()){
            //查看(你是取出)栈顶的结点
            cur  = stack.peek();
            //如果当前结点没有孩子结点(叶子结点)
            //或者孩子结点都已经被打印过(这里不可能出现有两个子结点却只打印了其中一个的情况)
            //说明该打印当前结点
            if((cur.left == null && cur.right == null) || (pre != null && (pre == cur.left || pre == cur.right))){
                System.out.print(cur.val + " "); //打印当前结点
                stack.pop();  //被打印的结点(当前结点)出栈
                pre = cur;   //更新pre的值
            }else{
                if(cur.right != null){   //若未轮到当前结点,将当前结点的右子结点、左子节点入栈
                    stack.push(cur.right);//注意:这里的入栈顺序是先right后left
                }
                if(cur.left != null){    //以保证从栈中取出时先left后right
                    stack.push(cur.left);
                }
            }
        }
    }


    //层序遍历
    public static void levelTraversal(Node root){
        Queue<Node> q = new LinkedList<>();
        q.add(root);
        while(!q.isEmpty()){
            Node temp = q.poll();
            if(temp != null){
                System.out.print(temp.val + " ");
                q.add(temp.left);
                q.add(temp.right);
            }
        }

    }

    public static void main(String[] args) {

        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);

        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        node3.left = node6;

        System.out.println("先序遍历:");
        preOrder(node1);
        System.out.println();

        System.out.println("先序遍历(非递归):");
        preOrderUnRec(node1);
        System.out.println();

        System.out.println("中序遍历:");
        inOrder(node1);
        System.out.println();

        System.out.println("中序遍历(非递归):");
        inOrderUnRec(node1);
        System.out.println();

        System.out.println("后序遍历:");
        postOrder(node1);
        System.out.println();

        System.out.println("后序遍历(非递归):");
        postOrderUnRec(node1);
        System.out.println();

        System.out.println("层序遍历:");
        levelTraversal(node1);
        System.out.println();

    }
}

结果:

先序遍历:
1 2 4 5 3 6 
先序遍历(非递归):
1 2 4 5 3 6 
中序遍历:
4 2 5 1 6 3 
中序遍历(非递归):
4 2 5 1 6 3 
后序遍历:
4 5 2 6 3 1 
后序遍历(非递归):
4 5 2 6 3 1 
层序遍历:
1 2 3 4 5 6 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值