最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

每天一個(gè)數(shù)據(jù)結(jié)構(gòu)知識(shí)——圖的廣度優(yōu)先遍歷BFS

2023-08-29 22:35 作者:一天三只皮卡丘  | 我要投稿

????????圖的廣度優(yōu)先遍歷和樹的廣度優(yōu)先遍歷類似,樹是層序遍歷,從根節(jié)點(diǎn)出發(fā)找到其所有的孩子結(jié)點(diǎn)。而圖的廣度優(yōu)先就是從一個(gè)結(jié)點(diǎn)開始,搜索所有的相鄰節(jié)點(diǎn)。而圖與樹不同點(diǎn)在于,樹不存在回路,所以搜索相鄰的結(jié)點(diǎn)不會(huì)搜到已經(jīng)訪問過的結(jié)點(diǎn),而圖搜索相鄰頂點(diǎn)時(shí)可能會(huì)重復(fù)訪問。所以,圖需要對每個(gè)頂點(diǎn)進(jìn)行標(biāo)記。

????????那么具體如何實(shí)現(xiàn)對圖的廣度優(yōu)先遍歷呢?之前了解到,樹的層序遍歷需要一個(gè)輔助隊(duì)列,BFS也是采取類似的方法。這里我們主要用到兩個(gè)圖的基本操作,一個(gè)是尋找第一個(gè)相鄰節(jié)點(diǎn)FirstNeighbor,一個(gè)是尋找相鄰節(jié)點(diǎn)的下一個(gè)相鄰節(jié)點(diǎn)NextNeighbor。同時(shí)定義一個(gè)bool型的數(shù)組visited[]標(biāo)記每個(gè)頂點(diǎn)有沒有被訪問過。

算法如下:

void BFS(G,v){? ?//從頂點(diǎn)v出發(fā)遍歷圖G

????visit(v);

????visited(v)=true;

????Enqueue(Q,v);????????//v進(jìn)入隊(duì)列Q

????while(isempty(Q)){ //隊(duì)列非空

????????Dequeue(Q,v);? //隊(duì)頭出隊(duì)

????????for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor){ //遍歷與隊(duì)頭頂點(diǎn)相鄰的所有頂點(diǎn)

????????????if(!visited(w)){ //鄰接節(jié)點(diǎn)沒有被訪問過

????????????????visit(w);

????????????????visited(w)=true;

????????????????Enqueue(Q,w); //訪問并入隊(duì)

????????????????????????????????}

????????????????????}

????????}

}

????????總體來看,廣度優(yōu)先遍歷和層序遍歷從實(shí)現(xiàn)方式來看十分類似(因?yàn)闃淦鋵?shí)就是一個(gè)特殊的圖),只是要記住廣度優(yōu)先遍歷每次訪問完需要標(biāo)記,訪問時(shí)也要排除掉標(biāo)記的。但是圖的存儲(chǔ)方式不同遍歷的次序也是不同的,鄰接表的遍歷次序是唯一的。

????????并且此方法對于非連接圖的遍歷也存在弊端,不過只需在遍歷停止后,再遍歷一遍visited[]數(shù)組,如果存在數(shù)組值為false,在以該節(jié)點(diǎn)為起始節(jié)點(diǎn)進(jìn)行BFS遍歷,直到?jīng)]有沒訪問的節(jié)點(diǎn)即可。實(shí)現(xiàn)方法如下:

void BFSTraverse(G){

for(i=0;i<G.vexnum;i++)visited[i]=false; //初始化visited數(shù)組

InitQueue(Q);

for(i=0;i<G.vexnum;i++){

????????if(visited[i]==false){?

????????????BFS(G,i);

????????????????}

}

}

????????顯然對于無向圖,調(diào)用BFS的次數(shù)=連通分量數(shù)。BFS的空間復(fù)雜度,輔助隊(duì)列最大為O(|v|)。此算法的主要開銷來自于訪問頂點(diǎn)和找到相鄰的鄰接點(diǎn),對于鄰接矩陣,尋找頂點(diǎn)鄰接點(diǎn)的時(shí)間復(fù)雜度為O(v),共有v個(gè)頂點(diǎn)因而查找所有頂點(diǎn)的鄰接點(diǎn)的時(shí)間復(fù)雜度為O(v^2)。對于鄰接表,查找每個(gè)頂點(diǎn)的鄰接點(diǎn)只需O(E)的時(shí)間復(fù)雜度,總時(shí)間復(fù)雜度為O(V+E)。

????????因?yàn)槲覀冊谶M(jìn)行廣度優(yōu)先時(shí)避免了重復(fù)訪問,因此有的邊不需要經(jīng)過就能訪問到所有的點(diǎn),那么我們把這些邊去掉就得到了廣度優(yōu)先生成樹。而由于鄰接表不唯一可能遍歷的序列不唯一,從而導(dǎo)致廣度優(yōu)先生成樹也不唯一。由此,我們可以想到,對于非連通圖的BFS可以得到廣度優(yōu)先森林。

????????在了解了廣度優(yōu)先搜索的原理后,下面我們開始學(xué)習(xí)其最重要的一個(gè)應(yīng)用——求最短路徑。最短路徑問題有幾個(gè)常見的場景:單源最短路徑,每對頂點(diǎn)間的最短路徑。BFS可以用來求無權(quán)圖的單元最短路徑。

????????我們只需在BFS算法的基礎(chǔ)上增加兩個(gè)數(shù)組,一個(gè)數(shù)組存放源節(jié)點(diǎn)到其他節(jié)點(diǎn)的距離,一個(gè)數(shù)組存放該路徑的上一個(gè)頂點(diǎn)。實(shí)現(xiàn)方法如下:

void BFS_Min_Distance(G,u){

visited(u)=true;

for(i=0;i<G.vexnum;i++){d[i]=-1;

path[i]=-1;

}//初始化路徑長度和路徑前驅(qū)節(jié)點(diǎn)

d[u]=0;

EnQueue(Q,u);

while(isEmpty(Q)){

DeQueue(Q,u);//隊(duì)頭元素出隊(duì)

for(w=FirstNeigobor(G,u);w>=0;w=NextNeighbor(G,u,w)){//訪問鄰接節(jié)點(diǎn)

while(!visited[w]){

d[w]=d[u]+1;

path[w]=u;

visited[w]=true;

EnQueue(Q,w);}

????????}//if

????}//while

}

通過回溯path數(shù)組,我們可以找到最短路徑,多么精妙的算法。同時(shí)我們可以發(fā)現(xiàn),通過廣度優(yōu)先生成樹的節(jié)點(diǎn)和根節(jié)點(diǎn)的距離就是最短路徑。

每天一個(gè)數(shù)據(jù)結(jié)構(gòu)知識(shí)——圖的廣度優(yōu)先遍歷BFS的評論 (共 條)

分享到微博請遵守國家法律
应城市| 郓城县| 读书| 即墨市| 贵定县| 拉萨市| 东明县| 积石山| 太湖县| 舞钢市| 望谟县| 阿合奇县| 汾阳市| 临澧县| 连平县| 甘孜县| 昆明市| 咸阳市| 泾源县| 乌恰县| 双流县| 寿光市| 湘乡市| 仁寿县| 石楼县| 本溪市| 探索| 六枝特区| 淳化县| 平果县| 滕州市| 东城区| 天峻县| 米脂县| 岳阳市| 牡丹江市| 北川| 屏山县| 安溪县| 布尔津县| 隆昌县|