美文网首页
广度优先算法BFS

广度优先算法BFS

作者: lifefruity | 来源:发表于2020-11-24 12:55 被阅读0次

    广度优先算法原理就是一个队列,先取一个初始点,然后找出所有临界的点放入队列,等上一层的消耗完了,就会消耗下一层的,以此类推。

    <?php 
    
    //BFS,广度优先算法
    /*
    
    例子中的图
    
            B   *****   D   *****  F
          * *         * *
       *    *        *  *
    A       *      *    *
       *    *    *      *
         *  *  *        *
            c   *****   E
    
    */
    
    //列出每个点的临界点
    $graph = [
        'A' => ['B', 'C'],
        'B' => ['A', 'C', 'D'],
        'C' => ['A', 'B', 'D', 'E'],
        'D' => ['B', 'C', 'E', 'F'],
        'E' => ['C', 'D'],
        'F' => ['D'],
    ];
    
    //广度优先是队列
    function BFS($graph, $s){//$s为开始的点
        $queue = [];
        $in = [];
        $in[$s] = 1;
        array_push($queue, $s);
        while(count($queue) > 0){
            $vertex = array_shift($queue);//消耗最前面的点,队列先进先出
            $nodes = $graph[$vertex];
            foreach($nodes as $w){
                if(!isset($in[$w])){//没有插入过
                    array_push($queue, $w);
                    $in[$w] = 1;
                }
            }
            echo $vertex;
        }
    }
    
    BFS($graph, 'A');//A为起点触发
    
    

    扩展1
    leetcode 102中,有计算二叉树的层序遍历,这个图也可以来计算下每层的元素
    具体思路:以A为起点,每层的目标是这样的: A | BC | DE | F ,需要知道是否是每层的最后一个,是的话下次层就加1。

    那么如何知道当前元素所在层的最后一个元素是什么呢?
    比如当前在x层,其实在x-1层就知道x层的最后一个是什么了。原因是在x-1层的最后一个时,queue里的最后一个肯定是x层的最后一个元素。所以就可以有一个每层的元素对于当前层最后一个的关系(见下面的希望得到例子),当到达每层的最后一个元素时,就可以缓存住下层的最后一个元素tmp,在遍历x+1层的时候,已经有了x+1层的最后一个元素,直接重复上述逻辑判断。
    希望得到:
    B C //B时最后一个是C。1个动作,放入元素
    C C //C时最后一个是C。3个动作,放入元素、层加1、得到下层的最后一个元素
    D E
    E E
    F F

    代码见:

    function BFS($graph, $s){//$s为开始的点
        $queue = [];
        $in[$s] = 1;
        $result = [];
        array_push($queue, $s);
        $flag = 1;
        $lastValue = '';
        while(count($queue) > 0){
            $vertex = array_shift($queue);//消耗最前面的点,队列先进先出
            $nodes = $graph[$vertex];
            if($flag){
                $lastValue = end($nodes);//初始化的下一层的最后一个元素
            }
            if(isset($tmp)){//当到达每一层的最后一个时候,需要知道下一层的最后一个是多少
                $lastValue = $tmp;
            }
            foreach($nodes as $w){
                if(!isset($in[$w])){//没有插入过
                    array_push($queue, $w);
                    $in[$w] = 1;
                }
            }
            if($vertex == $lastValue){
                //跑当前层的时候,知道当前层的最后一个是多少(因为肯定在上层已经计算出来了),
                //所以当vertex等于那个值的时候(说明是最后一个了),又可以计算下一层的最后一个了
                $flag = 1;
                $tmp = end($queue);
            }else{
                $flag = 0;
            }
            
            if($vertex == $s){
                $result[0][] = $vertex;
                $j++;
            }elseif($vertex == $lastValue){
                $result[$j][] = $vertex;
                $j++;
            }elseif($vertex != $lastValue){
                $result[$j][] = $vertex;
            }
            echo $vertex.$lastValue."<br>";
        }
        return $result;
    }
    

    相关文章

      网友评论

          本文标题:广度优先算法BFS

          本文链接:https://www.haomeiwen.com/subject/wmeiiktx.html