js搞定树结构,看这一篇就够了!

263 阅读1分钟

树是数据结构与算法中一种非常重要的结构,在难以计数的方面都使用了树结构。比如hash表的索引使用了链表和红黑树、diff算法查找dom树结构、堆存储是完全二叉树的一种等等。

接下来我们就来看一下js中树的基本方法。

树结构

root = {
    val: 2,
    left: {
        val: 2,
        left: null,
        right: {
            val: 5,
            left: null,
            right: null
        }
    },
    right: {
        val: 3,
        left: null,
        right: {
            val: 4,
            left: null,
            right: null
        }
    }
}

console.log(root.val);
console.log(root.left.right.val);
console.log(root.left.left);

我们用对象来模拟树结构

遍历方法

前序、中序、后续的递归用dfs模拟栈,也可以迭代手动操作栈

前序遍历

       //递归
        function foo(root, res = []) {
            if (root === null) {
                return res;
            }
            res.push(root.val);
            foo(root.left, res);
            foo(root.right, res);
            return res;
        }

        //迭代
        // 前序遍历:中左右
        // 压栈顺序:右左中
        function foo(root, res = []) {
            const stack = [];
            if (root) stack.push(root);
            while (stack.length) {
                const node = stack.pop();
                if (!node) {
                    res.push(stack.pop().val);
                    continue;
                }
                if (node.right) stack.push(node.right); // 右
                if (node.left) stack.push(node.left); // 左
                stack.push(node); // 中
                stack.push(null);
            };
            return res;
        };

中序遍历

        //递归
        function foo(root, res = []) {
            if (root === null) {
                return res;
            }
            foo(root.left, res);
            res.push(root.val);
            foo(root.right, res);
            return res;
        }

        //迭代
        //  中序遍历:左中右
        //  压栈顺序:右中左
        function foo(root, res = []) {
            const stack = [];
            if (root) stack.push(root);
            while (stack.length) {
                const node = stack.pop();
                if (!node) {
                    res.push(stack.pop().val);
                    continue;
                }
                if (node.right) stack.push(node.right); // 右
                stack.push(node); // 中
                stack.push(null);
                if (node.left) stack.push(node.left); // 左
            };
            return res;
        };

后序遍历

        //递归
        function foo(root, res = []) {
            if (root === null) {
                return res;
            }
            foo(root.left, res);
            foo(root.right, res);
            res.push(root.val);
            return res;
        }

        //迭代
        // 后续遍历:左右中
        // 压栈顺序:中右左
        var postorderTraversal = function (root, res = []) {
            const stack = [];
            if (root) stack.push(root);
            while (stack.length) {
                const node = stack.pop();
                if (!node) {
                    res.push(stack.pop().val);
                    continue;
                }
                stack.push(node); // 中
                stack.push(null);
                if (node.right) stack.push(node.right); // 右
                if (node.left) stack.push(node.left); // 左
            };
            return res;
        };

层序遍历

bfs操作队列

function foo(root) {
            if (!root) return [];
            let res = [], queue = [root];
            while (queue.length > 0) {
                let len = queue.length;
                let arr = [];
                while (len) {
                    let node = queue.shift();
                    arr.push(node.val);
                    if (node.left) queue.push(node.left);
                    if (node.right) queue.push(node.right);
                    len--
                }
                res.push(arr);
            }
            return res;
        }

写了四种遍历方式实现,实现又分为迭代和递归,先写这么多,还有不少内容有时间了在来加。


记录记录!