二叉树遍历【递归&非递归】


遍历代码

递归法

public class BinaryTreeTest {

    public static void main(String[] args) {
        System.out.println("开始先序遍历");
        preOrderTraversal(getRootOfBinaryTree());
        System.out.println();

        System.out.println("开始中序遍历");
        middleOrderTraversal(getRootOfBinaryTree());
        System.out.println();

        System.out.println("开始后序遍历");
        postOrderTraversal(getRootOfBinaryTree());

    }

    /**
     * 先序遍历 从上至下,先遍历左子树 到叶子节点 再从往上把所有的右节点遍历完
     * @param node
     */
    public static void preOrderTraversal(IntNode node){
        if(Objects.isNull(node)){
            return;
        }
        System.out.print(node.self + " ");
        preOrderTraversal(node.left);
        preOrderTraversal(node.right);
    }

    /**
     * 中序遍历 遍历完左子树 再访问跟 再访问右子树
     * @param node
     */
    public static void middleOrderTraversal(IntNode node){
        if(Objects.isNull(node)){
            return;
        }
        middleOrderTraversal(node.left);
        System.out.print(node.self + " ");
        middleOrderTraversal(node.right);
    }

    /**
     * 后序遍历 左-中-右
     * @param node
     */
    public static void postOrderTraversal(IntNode node){
        if(Objects.isNull(node)){
            return;
        }
        postOrderTraversal(node.left);
        postOrderTraversal(node.right);
        System.out.print(node.self + " ");
    }

    public static IntNode getRootOfBinaryTree(){
        IntNode root = new IntNode(1);
        IntNode node2 = new IntNode(2);
        IntNode node3 = new IntNode(3);
        IntNode node4 = new IntNode(4);
        IntNode node5 = new IntNode(5);
        IntNode node6 = new IntNode(6);
        IntNode node7 = new IntNode(7);
        IntNode node8 = new IntNode(8);
        IntNode node9 = new IntNode(9);
        IntNode node10 = new IntNode(10);
        IntNode node11 = new IntNode(11);
        IntNode node12 = new IntNode(12);
        IntNode node13 = new IntNode(13);

        root.left = node2;
        root.right = node3;

        node2.left = node4;
        node2.right = node5;

        node4.left = node8;

        node3.left = node6;
        node3.right = node7;

        node6.left = node9;
        node6.right = node10;

        node9.left = node11;

        node7.right = node12;

        node12.left = node13;

        return root;
    }

}

先序非递归

    public static void preOrderTraversalNotRecursion(IntNode node){
        if(Objects.isNull(node)){
            return;
        }
        Stack<IntNode> stack = new Stack();
        //从头部开始压栈 弹出 压右节点 压做节点 弹出 重复上述动作
        stack.push(node);
        while(!stack.isEmpty()){
            IntNode currentNode = stack.pop();
            System.out.print(currentNode.self + " ");
            //栈是先进后出 先序是中 左 右,要反着来 先压右
            if(currentNode.right!=null){
                stack.push(currentNode.right);
            }
            if(currentNode.left!=null){
                stack.push(currentNode.left);
            }
        }
    }

中序非递归

    /**
     * 中序遍历 非递归
     * @param node
     */
    public static void middleOrderTraversalNotRecursion(IntNode node){
        if(Objects.isNull(node)){
            return;
        }
        Stack<IntNode> stack = new Stack();
        stack.push(node);
        //从头部开始压栈 弹出 压右节点 压做节点 弹出 重复上述动作
        IntNode leftNode = node;
        while((leftNode = leftNode.left)!=null){
            stack.push(leftNode);
        }
        while(!stack.isEmpty()){
            IntNode currentNode = stack.pop();
            System.out.print(currentNode.self + " ");
            //栈是先进后出 先序是中 左 右,要反着来 先压右
            if(currentNode.right!=null){
                middleOrderTraversalNotRecursion(currentNode.right);
            }
        }
    }

后续非递归

    public static void postOrderTraversalNotRecursion(IntNode node){
        if(Objects.isNull(node)){
            return;
        }
        Stack<IntNode> stack = new Stack();
        Stack<IntNode> targetStack = new Stack();
        //从头部开始压栈 弹出 压右节点 压做节点 弹出 重复上述动作
        stack.push(node);
        while(!stack.isEmpty()){
            IntNode currentNode = stack.pop();
            targetStack.push(currentNode);
            //先压左 再压右
            if(currentNode.left!=null){
                stack.push(currentNode.left);
            }
            if(currentNode.right!=null){
                stack.push(currentNode.right);
            }
        }
        while(!targetStack.isEmpty()){
            System.out.print(targetStack.pop().self + " ");
        }
    }

二叉树DEMO 

遍历结果


开始先序遍历
1 2 4 8 5 3 6 9 11 10 7 12 13 
开始中序遍历
8 4 2 5 1 11 9 6 10 3 7 13 12 
开始后序遍历
8 4 5 2 11 9 10 6 13 12 7 3 1 

遍历思路

所谓的先 中 后都是基于中间的节点而言的

先序遍历【中 左 右】

从上至下遍历一遍最左侧的节点,到了叶子结点,往上返回遍历有右子节点的节点(这个时候是从下往上遍历),

左子树遍历完,开始遍历右子树过程一样(重复上面过程)

中序遍历【左 中 右】

从下至上,从最左侧的叶子结点往上走,有右侧节点遍历右侧节点,无右侧节点继续往上走

上侧无节点 遍历右子树,和上述步骤一样

后续遍历【左 右 中】

从下往上,从最左侧的节点开始,找他的右侧兄弟节点,若右侧兄弟节点不存在,往上遍历

若该侧的树都遍历完了,跳过跟节点,遍历右侧的子树,遍历步骤和上述步骤一样

小测试-看这个的三种遍历顺序如何

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值