二叉树的中序遍历js实现

816 阅读2分钟

二叉树理解起来也不难,一个根节点可以有左右两子树,而左右两个子树也可以有它们的子树。我们所比较陌生的,是如果要遍历每个元素,是一种怎样的遍历过程?

二叉树的常见遍历方法有前序,中序,后序遍历

图片源于B站教程

FF3FFFB4ED5D99543F270308105A59CE.jpg

我这里介绍的是中序遍历的方法:

递归方法

先遍历左子树直到最后一个,输出C,

再遍历这个节点的右子树。由于示例中C节点没有右子树,则会回到它的上一级并输出根节点B,遍历B的右子树

由于D节点没有左子树,输出D,D也没有右子树,回到上一级输出A节点

这便是一个递归遍历的过程

var inorderTraversal = function (root) {
            // res用于存放遍历过程的数组
            const res = []
            // rec为递归函数
            const rec = (n) => {
                // 如果n为空,则结束这次递归,并返回上一层递归
                if (!n) return
                rec(n.left)
                res.push(n.val)
                rec(n.right)
            }
            rec(root)
            return res
        };

迭代循环方法

这个方法需要引入栈的知识点,遵循后进后出的规则

image.png

遍历左子树,会把每一个节点推入栈中,当p指向null时,结束内层循环并将推出C,输出C。

将C节点右子树赋给p指针,用于C节点没有右子树,此时p为null,但栈的长度不为0,仍会继续循环。此时会推出B,输出B。在进入B的右子树,将D推入栈中

image.png

D没有左子树,将D推出,输出D

依次循环这个过程

var inorderTraversal = function(root) {
    const res = [];
    // 将stack看成一个栈的模型
    const stack = [];
    // p指针指向root根节点
    let p = root;
    // p不为null或者栈的长度不为0
    while (p || stack.length) {
        // 将所有节点的左节点全部推入栈中
        while (p) {
            stack.push(p);
            p = p.left;
        }
        // 逐一访问每个节点及其右节点
        const n = stack.pop();
        res.push(n.val)
        p = n.right;
    }
    return res
};