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

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

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

dfs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>tree</title>
</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>
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值