從頭開始復(fù)習(xí)算法之我們來簡單的應(yīng)用一下BFS

今天中午的時候呢?我簡單介紹了一下廣度優(yōu)先搜索和深度優(yōu)先搜索蛾号。關(guān)于這兩個概念吧熬尺,如果不知道的時候會感覺很難 但是一旦理解了這個東西 就感覺很簡單褂始。
既然今天談到了BFS,并且好多人都說BFS是很多算法的基礎(chǔ)跪帝,那么我就從基礎(chǔ)開始說起 簡單談一下BFS的應(yīng)用吧今膊。

一、 求BFS兩點(diǎn)之間的路徑

看了標(biāo)題伞剑,可能有點(diǎn)不明白對吧斑唬,先看我們的圖



首先我們根據(jù)上一篇文章的想法來寫一下BFC的代碼吧:

// 圖
let graph = {
    'A':['B','C'],
    'B':['A','C','D'],
    'C':['A','B','D','E'],
    'D':['B','C','E'],
    'E':['C','D','F'],
    'F':['E']
}
function dfs(graph,startPoint){
    let queue = [];
    let result = []

    queue.push(startPoint);
    result.push(startPoint);

    while(queue.length>0){
        let point = queue.shift();
        let nodes = graph[point];
        for(let node of nodes){
            if(result.includes(node)) continue;
            result.push(node);
            stack.push(node);
        }
    }
    return result
}

上面就是上一篇文章深入原理講的BFS的代碼,如果有不懂的纸泄,可以返回上一篇文章進(jìn)行專研赖钞,我這里就不多加贅述了。
在一篇文章講到BFS聘裁,我們是從一顆樹引入的雪营。我當(dāng)時講到:在廣度優(yōu)先搜索之下,圖就是沒確定起點(diǎn)的樹衡便。例如我們將起來設(shè)定成A献起,其實(shí)我們也能把樹形結(jié)構(gòu)給畫出來:



如果我們能畫出這個樹的話,其實(shí)就能明白我說得的意思镣陕。如果我們設(shè)定的起點(diǎn)是A谴餐,那么F到A點(diǎn)的路徑就是:F->E->C->A;B點(diǎn)到A的路徑就是B->A
我們來修改一下前面的代碼吧:

// 別問我為什么修改了一下上面的代碼呆抑。其實(shí)一個意思
// 其實(shí)我在為明天中午的復(fù)習(xí)set做準(zhǔn)備岂嗓,順便復(fù)習(xí)了一下api 哈哈
function bfs(graph,startPoint){
    let queue = [];
    let result = new Set();
    let tree = {};

    queue.push(startPoint);
    result.add(startPoint);
    tree[startPoint] = ""

    while(queue.length > 0){
        let point = queue.shift();
        let nodes = graph[point];
        for(let node of nodes){
            if(result.has(node)) continue;
            result.add(node)
            queue.push(node)
            tree[node] = point;
        }
    }
    return tree
}

function shortDistance(tree,point){
    let node = point
    let distance = [point]
    while(tree[node]!=""){
        node = tree[node];
        distance.push(node);
    }
    return distance;
}

怎么理解上面的代碼呢?
很簡單鹊碍,就是將每個數(shù)據(jù)在出棧的時候記錄一下他的父節(jié)點(diǎn)是誰厌殉?如下圖所示:

戶口薄

如上圖所示,第一段代碼就相當(dāng)于給每一個元素建立了一個戶口薄侈咕,每個人的身份信息全部都填寫到了本本上面公罕,如果想找找到路徑,就直接從當(dāng)前節(jié)點(diǎn)開始盤問耀销。例如:E到A的路徑楼眷,就可以如下操作:

就能找出E->C->A的路徑。

二、 求BFS的最短路徑/距離

上面用一個例子簡單的介紹了一個廣度深度優(yōu)先算法的兩個點(diǎn)的路徑罐柳,但是其實(shí)很容易就會發(fā)現(xiàn)得到的答案并不是唯一的掌腰,比如就上面的條件來說,我也可以畫成這樣的樹 也能滿足需求:



如上所示张吉,其實(shí)這樣也是能滿足需求的辅斟,針對這種比較不唯一的情況 我就大膽了再給其加上限定條件。如下圖所示:



如上圖所示芦拿,A到C的路徑 一共有A->C和A->B->C。但是A->C的距離是5查邢,A->B->C的距離是3蔗崎。所以此時的最短路徑應(yīng)該是A->B->C。

具體的排序方式 同樣我們用下面的一組套圖來解釋一下扰藕。

同樣我們先把A放進(jìn)容器中缓苛。


將A移出容器,并將與A相連的B邓深,C 移入容器內(nèi)未桥,再比較與B,C相連的距離誰比較近芥备。明顯B距離A比較近冬耿。

將B移出容易,并且將與B相連的C,D加入容器內(nèi)萌壳,此時我們發(fā)現(xiàn)容器內(nèi)有兩個C亦镶,而后者的C比前者要小。

image.png

將距離比較小的C和距離比較大的C調(diào)換位置袱瓮,然后移出缤骨,并且將與C相連的D,E加入容易內(nèi)。

同理將容器內(nèi)比較小的D移出容器尺借,當(dāng)我們再次將容器內(nèi)比較小的C和D移出時绊起,發(fā)現(xiàn)之前移出的數(shù)據(jù)里面中已經(jīng)存在C,D燎斩。此時就將C虱歪,D給舍棄

最后就這樣得到了所謂的最短路徑了。來我們用代碼來演示一下:

function bfs(graph,startPoint){

    let queue = [];
    let result = {};
    let seen = new Set();

    let distance =  initDistance(graph,startPoint);

    queue.push({distance:0,name:startPoint});
    result[startPoint] ={parent:"",distance:0,};

    while(queue.length > 0){

        let point = queue.shift();
        let dist = point.distance;
        let vertex = point.name;
        seen.add(vertex);
        let nodes = graph[vertex]
        for(let node in nodes){
            if(!seen.has(node)&&dist+nodes[node]<distance[node]) {
                result[node]= {parent:vertex,distance:dist+nodes[node]};
                distance[node] = dist+nodes[node];
                queue.push({distance:dist+nodes[node],name:node});
            }
            
        }
        queue.sort((a,b)=>{
            return a.distance-b.distance;
        })

    }
    console.log(result)
    return result;
}

那么此時我們的數(shù)據(jù)結(jié)構(gòu)就應(yīng)該是這個樣子了哦:

let graph = {
    'A':{'B':1,'C':5},
    'B':{'A':1,'C':2,'D':3},
    'C':{'A':5,'B':2,'D':4,'E':10},
    'D':{'B':3,'C':4,'E':3},
    'E':{'D':3,'C':10,'F':5},
    'F':{'E':5}
}

說在最后

關(guān)于BFS用法呢瘫里?其實(shí)還是比較簡單的实蔽。也是只要想通了,寫出來還是比較簡單的谨读。我這里呢局装?就簡單的寫一兩個例子來給諸位當(dāng)一個敲門磚吧。如果之前有研究過第二個問題,其實(shí)很容易就發(fā)現(xiàn)其實(shí)第二個問題就是大名鼎鼎的Dijkstra算法铐尚。如果對圖有深層次的興趣拨脉,也可以深入了解一下哦 畢竟知道總比不知道好。

好了宣增,好了 中午睡覺的時間真的又被我活生生的寫完了玫膀,看來今天又沒午覺睡了。還是去躺躺一下吧爹脾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末帖旨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子灵妨,更是在濱河造成了極大的恐慌解阅,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泌霍,死亡現(xiàn)場離奇詭異货抄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)朱转,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門蟹地,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人藤为,你說我怎么就攤上這事怪与。” “怎么了缅疟?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵琼梆,是天一觀的道長。 經(jīng)常有香客問我窿吩,道長茎杂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任纫雁,我火速辦了婚禮煌往,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘轧邪。我一直安慰自己刽脖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布忌愚。 她就那樣靜靜地躺著曲管,像睡著了一般。 火紅的嫁衣襯著肌膚如雪硕糊。 梳的紋絲不亂的頭發(fā)上院水,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天腊徙,我揣著相機(jī)與錄音,去河邊找鬼檬某。 笑死撬腾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恢恼。 我是一名探鬼主播民傻,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼场斑!你這毒婦竟也來了漓踢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤漏隐,失蹤者是張志新(化名)和其女友劉穎彭雾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锁保,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年半沽,在試婚紗的時候發(fā)現(xiàn)自己被綠了爽柒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡者填,死狀恐怖浩村,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情占哟,我是刑警寧澤心墅,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站榨乎,受9級特大地震影響怎燥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜜暑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一铐姚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肛捍,春花似錦隐绵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缀蹄,卻和暖如春峭跳,著一層夾襖步出監(jiān)牢的瞬間膘婶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工坦康, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留竣付,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓滞欠,卻偏偏與公主長得像古胆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子筛璧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容