likes
comments
collection
share

栈的力量:解锁树的前中后遍历之谜

作者站长头像
站长
· 阅读数 36

前言

对于树的结构大家应该不陌生了,对于其前、中、后遍历可以通过递归的方式来实现,那么还可以通过什么来实现呢?

通过结构来实现。

正文

树结构

树的结构:

function TreeNode(val) {
    this.val = val;
    this.left = null;
    this.right = null;
}

栈的力量:解锁树的前中后遍历之谜 定义一个下面的树结构来分析其前、中、后序遍历的结、果:

栈的力量:解锁树的前中后遍历之谜

const root = {
    val: 1,
    left:{
        val: 2,
        left: {
            val: 4,
        },
        right: {
            val: 5,
        }
    },
    right:{
        val: 3,
        right: {
            val: 6,
        }
    }
}

前序遍历

结果为:1 2 4 5 3 6

前序遍历的规则:根左右

递归实现

  • 先判断该节点是否为空,如果为空就返回
  • 输出该节点的值(节点)
  • 采用递归将该节点的左节点传入(节点)
  • 采用递归将该节点的右节点传入(节点)
function preorder(node) {
        if(!node) {
          return;  
        }
        console.log(node.val);
        preorder(node.left);
        preorder(node.right);
}

栈实现(力扣144题)

var preorderTraversal = function(root) {
const res = [];
const stack = [];
stack.push(root);

while (stack.length) {
    if (!root) return [];
    const cur = stack.pop();
    res.push(cur.val);
    if (cur.right) {
        stack.push(cur.right);
    }
    if (cur.left) {
        stack.push(cur.left);
    }
}

return res;
};

该树的前序遍历通过图来解释如下: 栈的力量:解锁树的前中后遍历之谜

分析:

  • 先将root入栈,然后出栈并赋值给cur
  • 将cur加入数组res
  • 先判断cur的right,如果存在,则压入栈
  • 在判断cur的left,如果存在,则压入栈(因为前序遍历为根左右,并且栈为先进后出,所以先判断右节点再判断左节点)
  • 一直循环至栈为空
  • cur=1时,3和2入栈
  • cur=2时,5和4入栈
  • cur=4
  • cur=5
  • cur=3时,6入栈
  • cur=6

中序遍历

结果为:4 2 5 1 3 6

中序遍历的规则:左根右

递归实现

  • 先判断该节点是否为空,如果为空就返回
  • 采用递归将该节点的左节点传入(节点)
  • 输出该节点的值(节点)
  • 采用递归将该节点的右节点传入(节点)
function inorder(node) {
    if (!node) {
        return;
    }
    inorder(node.left);
    console.log(node.val);
    inorder(node.right);
}

栈实现(力扣94题)

var inorderTraversal = function(root) {
    if (!root) return [];
    const res = [];
    const stack = [];
    let cur = root;

    while (stack.length || cur) {
        while (cur) {
            stack.push(cur);
            cur = cur.left;
        }

        cur = stack.pop();
        res.push(cur.val);
        cur = cur.right;
    }

    return res;
    };

该树的中序遍历通过图来解释如下:

栈的力量:解锁树的前中后遍历之谜

分析:

  • 从根节点一直遍历左节点,遍历到的节点入栈,直到该节点不存在左节点时,也就是4,将该节点的值出栈
  • 再将顶部元素2出栈,将其右节点赋值给cur
  • 一直循环,直到栈为空或者cur为空(因为右节点没有入栈,只有左节点入栈,右节点直接赋值给cur)
  • cur=4时,1和2入栈
  • cur=2
  • cur=5
  • cur=1
  • cur=3
  • cur=6

后序遍历

结果为:4 5 2 6 3 1 后序遍历的规则:左右根

递归实现

  • 先判断该节点是否为空,如果为空就返回
  • 采用递归将该节点的左节点传入(节点)
  • 采用递归将该节点的右节点传入(节点)
  • 输出该节点的值(节点)
function postorder(node) {
    if (!node) {
        return;
    }
    postorder(node.left);
    postorder(node.right);
    console.log(node.val);
}

栈实现(力扣145题)

var postorderTraversal = function(root) { 
          if (!root) return [];
        const res = [];
        const stack = [];
        stack.push(root);
        
        
        while (stack.length) {
         
            const cur = stack.pop();
            res.unshift(cur.val);
             if (cur.left) {
                stack.push(cur.left);
            }
            if (cur.right) {
                stack.push(cur.right);
            }
        }
        
        return res;
        };

该树的后序遍历通过图来解释如下:

栈的力量:解锁树的前中后遍历之谜

分析:

  • 后序和先序差不多,相当于反着的,所以在后序就是向数组头部加入
  • cur=1时,2和3入栈
  • cur=3时,6入栈
  • cur=6
  • cur=2时,4和5入栈
  • cur=5
  • cur=4

结语

栈的力量:解锁树的前中后遍历之谜

转载自:https://juejin.cn/post/7383917346643329064
评论
请登录