• 广度优先搜索,深度优先搜索--JavaScript-Mr.Ember


    广度优先搜索,深度优先搜索-JavaScript

     摘要:

    掌握好数据结构对前端和后端都很有必要,js中DOM可以跟树这种数据结构联系起来,相信大家都不陌生。

    遍历下面这颗DOM树,遍历到节点时,打印当前节点和类名

        <div class="root">
            <div class="box1">
                <p class="pnode">nini</p>
            </div>
            <div class="box2">
                
            </div>
            <div class="box3">
                <span class="spannode">lalal</span>
            </div>
        </div>

     1. 深度优先搜索

    深度优先遍历是指从某个顶点出发,首先访问这个顶点,然后找出刚访问这个结点的第一个未被访问的邻结点,然后再以此邻结点为顶点,继续找它的下一个顶点进行访问。重复此步骤,直至所有结点都被访问完为止。

    下面是深度优先搜索的顺序图

    递归版:

    function deepTraversal(node){
      let nodes=[];
      if(node!=null){
        nodes.push[node];
        let childrens=node.children;
        for(let i=0;i<childrens.length;i++)
          deepTraversal(childrens[i]);
        }
      return nodes;
    }

    非递归版:

    function deepTraversal(node) {
        let nodes = [];
        if(node != null) {
            let stack = []; //存放将来要访问的节点
            stack.push(node);
            while(stack.length !=0) {
                let item = stack.pop();   //正在访问的节点
                nodes.push(item);
                let childrens = item.children;
                for(let i = childrens.length-1; i>=0; i--) {  //将现在访问的节点的子节点存入stack,供将来访问
                    stack.push(childrens[i])
                }
            }
        }
        return nodes;
    }

    非递归版呢,先把元素放在数组里,然后是把数据的最后一项pop出去,判断当前元素是否有子节点,如果有的话推进数组里,直到数组里没有数据停止循环。 

    2.  广度优先搜索

      广度优先遍历是从某个顶点出发,首先访问这个顶点,然后找出刚访问这个结点所有未被访问的邻结点,访问完后再访问这些结点中第一个邻结点的所有结点,重复此方法,直到所有结点都被访问完为止。

    下面是广度优先搜素的顺序图:

    递归版:

    function wideTraversal(node) {
        let nodes = [],i=0;
        if(node != null) {
            nodes.push(node);
            wideTraversal(node.nextElementSibling);
            node = nodes[i++];
            wideTraversal(node.firstElementChild);
        }
        return nodes
    }

    非递归版:

    function wideTraversal(node) {
        let nodes = [],i=0;
        if(node != null) {
            let stack = []; //存放将来要访问的节点
            stack.push(node);
            while(stack.length !=0) {
                let item = stack.shift();   //正在访问的节点
                nodes.push(item);
                let childrens = item.children;
                for(let i = 0; i<childrens.length; i++) {  //将现在访问的节点的子节点存入stack,供将来访问
                    stack.push(childrens[i])
                }
            }
        }
        return nodes
    }

    广度优先搜索非递归版和深度优先搜索的递归版思想差不多,一个是pop最后一个元素,一个是shift第一个元素,再把子元素放在一个数组最后,这样再进行数组的处理时会先遍历父元素,子元素最后遍历。达到广度搜索的目的。

    结论:

    对于深度优先搜索来说,打印了两个的执行速度,递归的处理速度相对较快点,但是对于广度优先搜索来说,非递归的执行速度比较快点。所以每个搜索都有自己的最好的算法。

  • 相关阅读:
    sp_executesql是参数部分的长度定义发生变化能否重用执行计划
    scope_identity ident_current @@identity
    Useful undocumented extended stored procedures
    Delphi7对XML的支持分析
    Eclipse基础--Eclipse启动过程
    《现象七十二变》歌词
    被擦掉的名字
    同义词
    资产负债表的阅读与分析
    三谈多态——善用virtual
  • 原文地址:https://www.cnblogs.com/teteWang-Ember/p/10252466.html
Copyright © 2020-2023  润新知