• 【二叉树】- 迭代遍历( js 实现前、中、后序)



    活动地址:CSDN21天学习挑战赛

    还是二叉树遍历 听说还可以使用非递归的方式 这次我们使用迭代法再来解决一遍二叉树的遍历


    递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。
    那么大家应该知道我们用栈也可以是实现二叉树的前后中序遍历了。

    **

    前序遍历(迭代法)

    我们先看一下前序遍历。

    前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。

    为什么要先加入右孩子,再加入左孩子呢? 因为这样出栈的时候才是中左右的顺序。
    不难写出如下代码:

    /**
     * Definition for a binary tree node.
     * function TreeNode(val, left, right) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.left = (left===undefined ? null : left)
     *     this.right = (right===undefined ? null : right)
     * }
     */
    /**
     * @param {TreeNode} root
     * @return {number[]}
     */
    var preorderTraversal = function(root) {
        let stack=[]
        let res = []
        let cur = null;
        if(!root) return res;
        root&&stack.push(root)
        while(stack.length){
            cur = stack.pop()
            res.push(cur.val)
            cur.right&&stack.push(cur.right)
            cur.left&&stack.push(cur.left)
        }
        return res
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    此时会发现貌似使用迭代法写出前序遍历并不难,确实不难。

    此时是不是想改一点前序遍历代码顺序就把中序遍历搞出来了?

    其实还真不行!

    但接下来,再用迭代法写中序遍历的时候,会发现套路又不一样了,目前的前序遍历的逻辑无法直接应用到中序遍历上。

    中序遍历(迭代法)

    为了解释清楚,我说明一下 刚刚在迭代的过程中,其实我们有两个操作:

    1. 处理:将元素放进result数组中
    2. 访问:遍历节点

    分析一下为什么刚刚写的前序遍历的代码,不能和中序遍历通用呢,因为前序遍历的顺序是中左右,先访问的元素是中间节点,要处理的元素也是中间节点,所以刚刚才能写出相对简洁的代码,因为要访问的元素和要处理的元素顺序是一致的,都是中间节点。

    那么再看看中序遍历,中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的

    那么在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素

    中序遍历,可以写出如下代码:

    /**
     * Definition for a binary tree node.
     * function TreeNode(val, left, right) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.left = (left===undefined ? null : left)
     *     this.right = (right===undefined ? null : right)
     * }
     */
    /**
     * @param {TreeNode} root
     * @return {number[]}
     */
    var inorderTraversal = function(root) {
        let stack = []
        let res = []
        let cur = root
        while(cur||stack.length){
            if(cur){
                stack.push(cur)
                cur = cur.left
            } else {
                cur = stack.pop()
                res.push(cur.val)
                cur = cur.right
            }
        }
        return res
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    后序遍历(迭代法)

    再来看后序遍历,先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了。

    /**
     * Definition for a binary tree node.
     * function TreeNode(val, left, right) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.left = (left===undefined ? null : left)
     *     this.right = (right===undefined ? null : right)
     * }
     */
    /**
     * @param {TreeNode} root
     * @return {number[]}
     */
    var postorderTraversal = function(root) {
        let stack = []
        let res = []
        let cur = root
        if(!root) return res
        stack.push(root)
        while(stack.length){
            cur = stack.pop()
            res.push(cur.val)
            cur.left&&stack.push(cur.left)
            cur.right&&stack.push(cur.right)
        }
        return res.reverse()
    
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

  • 相关阅读:
    AQS原理及源码解析
    React学习---初识React
    11.22二叉树相关OJ
    面试三(多进程调用同一个动态库问题)
    基于文件上传漏洞获得网站 shell 权限
    Linux 用户系统
    AIoT通用组件服务攻略之快速定位http数据推送失败
    深度学习入门(四十二)计算机视觉——目标检测和边界框
    刘二大人 PyTorch深度学习实践 笔记 P5 用PyTorch实现线性回归
    【Rust】简介、安装和编译
  • 原文地址:https://blog.csdn.net/weixin_45771601/article/details/126215281