非递归深度优先遍历树结构数据

js 非递归深度优先遍历树结构数据

使用递归方法实现对树的遍历效率非常低,下面利用栈的特性来实现对树的深度优先遍历;

非递归深度优先遍历树结构数据_第1张图片


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>treetitle>
head>
<body>
    <script>
        var tree = {
            name : '中国',
            children : [
            {
                name : '北京',
                children : [
                {
                    name : '朝阳群众'
                },
                {
                    name : '海淀区'
                },
                {
                    name : '昌平区'
                }
                ]
            },
            {
                name : '浙江省',
                children : [
                {
                    name : '杭州市',
                    code : 0571,
                },
                {
                    name : '嘉兴市'
                },
                {
                    name : '绍兴市'
                },
                {
                    name : '宁波市'
                }
                ]
            }
            ]
        };

        // 深度遍历 --- 使用栈
        function dfs(tree, name){
            var stack = [];

            // 从根节点往下遍历
            while (tree) {
                if (tree.name === name) {
                    return tree;
                }

                // 若节点有孩子节点,继续遍历
                if (hasProperty(tree, 'children') && tree.children.length > 0) {
                    // 若节点有不止一个孩子节点,则将孩子节点非第一个节点全部压入栈中
                    // 因为栈是先进后出,为了实现按序访问,需要将孩子节点倒序压入栈
                    for (var i = tree.children.length - 1; i > 0; i--) {
                        stack.push(tree.children[i])
                    }
                    // 访问当前节点的第一个子节点
                    tree = tree.children[0];
                } else {
                    // 节点没有孩子节点,则当前节点为叶子节点
                    // 判断栈中是否有节点, 若有则继续遍历
                    if (stack.length > 0) {
                        tree = stack.pop();
                    } else {
                        // 栈中已经不存在节点,退出遍历,节点不存在
                        return ;
                    }
                }
            }

            return ;
        }

        // 广度遍历 --- 使用队列
        function bfs(tree, name) {
            var queue = [];

            // 从根节点往下遍历
            while (tree) {
                if (tree.name === name) {
                    return tree;
                }

                // 若节点有孩子节点,继续遍历
                if (hasProperty(tree, 'children') && tree.children.length > 0) {
                    // 将该节点的非第一个子节点顺序加入队列中
                    for (var i = 1; i < tree.children.length; i++) {
                        queue.push(tree.children[i])
                    }
                    // 直接访问当前节点的第一个子节点
                    tree = tree.children[0];
                } else {
                    // 节点没有孩子节点,则当前节点为叶子节点
                    // 判断栈中是否有节点, 若有则继续遍历
                    if (queue.length > 0) {
                        tree = queue.shift();
                    } else {
                        // 栈中已经不存在节点,退出遍历,节点不存在
                        return ;
                    }
                }
            }

            return ;
        }

        function hasProperty(node, prop) {
            if (node && node.hasOwnProperty(prop)) {
                return true;
            }
            return false;
        }

        const node = dfs(tree, '杭州市');
        console.log(node); // { name: '杭州市', code: 0571 }



    script>
body>
html>

你可能感兴趣的:(javascript)