目錄
一、樹的廣度優先遍歷
通過根節點,可以找到下一層的結點2,3,4通過234又可以找到再下一層的結點5678
二、圖的廣度優先遍歷
廣度優先序列:21453748
三、樹VS圖
樹
不存在“迴路”,搜索相鄰的結點時,不可能搜到已經訪問過的結點
圖
搜索相鄰的頂點時,有可能搜到已經訪問過的頂點
樹的廣度優先遍歷(層次遍歷)
①若樹非空,則根節點入隊
②若隊列非空,隊頭元素出隊並訪問,同時將該元素的孩子依次入隊
③重複②直到隊列爲空
四、代碼實現
BFS要點
1.找到與一個頂點相鄰的所有頂點
2.標記哪些頂點被訪問過
3.需要一個輔助隊列
bool visited[MAX_VERTEX_NUM]; //訪問標記數組
//廣度優先遍歷
void BFS(Graph G,int v){ //從頂點v出發,廣度優先遍歷圖G
visit(v); //訪問初始頂點v
visited[v] = TRUE; //對v做已訪問標記
Enqueue(Q,v); //頂點v入隊列Q
while(!isEmpty(Q)){
DeQueue(Q,v); //頂點v出隊列
for(w = FirstNeighbor(G,v); w >= 0; w = NextNeighbor(G,v,w)) //檢測v所有鄰接點
if(!visited[w]){ //w爲v的尚未訪問的鄰接頂點
visit[w]; //訪問頂點w
visited[w] = TRUE; //對w做已訪問標記
EnQueue(Q,w); //頂點w入隊列
}//if
}//while
}
五、廣度優先遍歷序列
從頂點1出發得到的廣度優先遍歷序列:12563748
從頂點2出發得到的廣度優先遍歷序列:21653748
從頂點3出發得到的廣度優先遍歷序列:34678215
六、遍歷序列的可變性
同一個圖的鄰接矩陣表示方式唯一,因此廣度優先遍歷序列唯一
同一個圖的鄰接表表示方式不唯一,因此廣度優先遍歷序列不唯一
七、算法存在的問題
如果是非連通圖,則無法遍歷完所有結點
八、BFS算法(Final版)
bool visited[MAX_VERTEX_NUM]; //訪問標記數組
void BSFTraverse(Graph G){ //對圖G進行廣度優先遍歷
for(i = 0; i < G.vexnum;++1)
visited[i] = FALSE; //訪問標記數組初始化
InitQueue(Q); //初始化輔助隊列Q
for(i = 0; i < G.vexnum;++1) //從0號頂點開始遍歷
if(!visited[i]) //對每個連通分量調用一次BFS
BFS(G,i); //vi未訪問過,從vi開始BFS
}
//廣度優先遍歷
void BFS(Graph G,int v){ //從頂點v出發,廣度優先遍歷圖G
visit(v); //訪問初始頂點v
visited[v] = TRUE; //對v做已訪問標記
Enqueue(Q,v); //頂點v入隊列Q
while(!isEmpty(Q)){
DeQueue(Q,v); //頂點v出隊列
for(w = FirstNeighbor(G,v); w >= 0; w = NextNeighbor(G,v,w)) //檢測v所有鄰接點
if(!visited[w]){ //w爲v的尚未訪問的鄰接頂點
visit[w]; //訪問頂點w
visited[w] = TRUE; //對w做已訪問標記
EnQueue(Q,w); //頂點w入隊列
}//if
}//while
}
結論:對於無向圖,調用BFS函數的次數 = 連通分量數
九、複雜度分析
空間複雜度:最壞情況,輔助隊列大小爲O(|V|)
時間複雜度
鄰接矩陣存儲的圖
訪問|V|個頂點需要O(|V|)的時間
查找每個頂點的鄰接點都需要O(|V|)的時間,而總共有|V|個頂點
時間複雜度 = O(|V|^2)
鄰接表存儲的圖
訪問|V|個頂點需要O(|V|)的時間
查找各個頂點的鄰接點共需要O(|E|)的時間
時間複雜度 = O(|V| + |E|)
十、廣度優先生成樹
鄰接矩陣和鄰接表存儲
另一種鄰接表存儲
總結
廣度優先生成樹由廣度優先遍歷過程確定、由於鄰接表的表示方式不唯一,因此基於鄰接表的廣度生成樹也不唯一
十一、廣度優先生成森林
對於非連通圖的廣度優先遍歷、可得到廣度優先生成森林