二叉树先序、中序、后序、层次遍历递归以及非递归算法实现

二叉树遍历算法详解
本文详细介绍了二叉树的先序、中序、后序及层次遍历算法,包括递归与非递归实现方式。通过栈和队列等数据结构,实现了不同遍历顺序的非递归解决方案。

最近写了一下关于二叉树的三种遍历算法的递归以及非递归实现,以及层次遍历算法实现

先序遍历递归实现

	/**
     * 先序遍历,根》左》右
     */
    public void beforeTraverse(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.val + "->");
        if (root.left != null) {
            beforeTraverse(root.left);
        }
        if (root.right != null) {
            beforeTraverse(root.right);
        }
    }

先序遍历非递归实现

	/**
     * 通过栈遍历二叉树,先序(思想就是:入栈即记录)
     */
    public List<String> beforeTraverseByStack(TreeNode root) {
         List<Integer> ans = new ArrayList<>();
        // 栈
        Deque<TreeNode> stack = new ArrayDeque<>();

        while (root != null || !stack.isEmpty()) {
            // 1. 左节点全部入栈,并且记录它们的值放到结果集中
            while (root != null) {
                stack.push(root);
                ans.add(root.val);
                root = root.left;
            }
            // 2. 依次出栈,并且看出栈的节点是否有右节点,有右节点则还需一直寻找其左节点入栈(同上)
            root = stack.pop().right;
        }
        return ans;
    }

中序遍历递归实现

	/**
     * 中序遍历,左》根》右
     */
    public void middleTraverse(TreeNode root) {
        if (root.left != null) {
            middleTraverse(root.left);
        }
        System.out.print(root.val + "->");
        if (root.right != null) {
            middleTraverse(root.right);
        }
    }

中序遍历非递归实现

	/**
     * 通过栈遍历二叉树,中序(思想就是:出栈即记录)
     */
    public List<String> middleTraverseByStack(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        // 栈
        Deque<TreeNode> stack = new ArrayDeque<>();

        while (root != null || !stack.isEmpty()) {
            // 1. 先左节点全部入栈
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            // 2. 一个个节点出栈,出栈的同时将他们放到结果集中,并且判断其有没有右节点,若有右节点则需将其左节点全部加入栈中(同上)
            root = stack.pop();
            ans.add(root.val);
            root = root.right;
        }
        return ans;
    }

后序遍历递归实现

	/**
     * 后序遍历,左》右》根
     */
    public void afterTraverse(TreeNode root) {
        if (root.left != null) {
            afterTraverse(root.left);
        }
        if (root.right != null) {
            afterTraverse(root.right);
        }
        System.out.print(root.val + "->");
    }

后序遍历非递归实现

	/**
     * 通过栈遍历二叉树,后序
     */
    public List<String> afterTraverseByStack(TreeNode root) {
        List<Integer> ans = new ArrayList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();

        // 2. 一个个节点出栈,并且判断其有没有右节点,没有右节点直接放入结果集中,若有右节点则需将其左节点全部加入栈中(同上)
        // 放入结果集中的条件:没有右节点或者右节点已经全部遍历完
        // 那么需要一个标识位,标识上一位放入结果集的节点是什么(即遍历完)
        TreeNode prev = null;
        while (root != null || !stack.isEmpty()) {
            // 1. 先左节点全部入栈
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            TreeNode node = stack.pop();
            // 没有右节点,放入结果集;或者右节点已经遍历完
            if (node.right == null || node.right == prev) {
                ans.add(node.val);
                prev = node;
            } else {
                // 还有右节点,重新入栈,并且其左孩子继续入栈
                stack.push(node);
                root = node.right;
            }
        }
        return ans;
    }

层次遍历算法实现

	/**
     * 层次(顺序)遍历,一层一层,从左向右
     * 需要引入队列这种数据结构,队列:先进先出,头进尾出
     * 因为既需要找到一个结点的左结点又需要找到右结点
     */
    public List<String> orderTraverse(TreeNode root) {
        // 使用集合代替队列,先进先出(出队列就是移除第0个元素)
        Queue<TreeNode> queue = new LinkedList<>();
        List<String> result = new ArrayList<>();    // 接受结果
        if (root == null) {
            return result;
        }
        list.add(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            result.add(node.val);
            if (node.left != null) {
                queue.add(node.left);
            }
            if (node.right != null) {
                queue.add(node.right);
            }
        }
        return result;
    }

总的来说,非递归算法就是引入辅助数据结构栈(或者其他),利用他们特殊的结构先进后出(其他)的特点,完成按要求的遍历

关于树的很多算法都是由他们变形而来的,但还是需要灵活的转变思维才能解决相应的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值