資料結構18————圖的深度優先遍歷(DFS)&廣度優先遍歷(BFS)
資料結構18————圖的深度優先遍歷(DFS)&廣度優先遍歷(BFS)
一. 目錄
二. 深度優先遍歷(DFS)
1.DFS遞迴定義
假設給定圖的所有狀態都是未曾訪問過.在G中任選一個點V作為初始點。則深度優先遍歷的定義如下:
首先訪問出發點V,並將其標記為已訪問過。然後依次從v出發搜尋v的每個鄰接點w。若w未曾訪問過,則以w為新的處發點繼續進行深度優先遍歷,直至圖中所有和源點v路徑相通的頂點均被訪問。若此時圖中仍有未訪問的頂點,則另選一個尚未訪問的頂點作為新的源點重複上述過程,直至圖中所有頂點均已被訪問為止。
圖的深度優先遍歷類似於圖的前序遍歷。採用搜尋方法的特點是儘可能對縱深方向進行搜尋。這種搜尋方法被稱為深度優先搜尋(Depth-First Search)
2.遍歷思路
- 訪問頂點v;
- 從v的未被訪問的鄰接點中選取一個頂點w,從w出發進行深度優先遍歷;
- 重複上述兩步,直至圖中所有和v有路徑相通的頂點都被訪問到。
3.虛擬碼
遞迴實現
(1)訪問頂點v;visited[v]=1;//演算法執行前visited[n]=0
(2)w=頂點v的第一個鄰接點;
(3)while(w存在){
if(w未被訪問)
從頂點w出發遞迴執行該演算法;
w=頂點v的下一個鄰接點;
}
非遞迴實現
(1) 棧S的初始化:visited[n=0]
(2 ) 訪問頂點v;visited[v]=1;頂點v入棧s
(3) while(棧S非空){
x=棧S的頂元素(不出棧);
if(存在並找到未曾訪問的x鄰接點w){
訪問w;visited[w]=1;
w入棧;
}else{
x出棧;
}
}
4.對鄰接矩陣儲存無向圖的進行DFS
完整程式碼在下文連結中,下同
int visited[MAXVEX];
void DFS(AdjMatrix *G,int i){ //i為出發點
int j;
visited[i]=1;
printf ("%c",G->Vex[i]);
for(j=0;j<G->vexnum ;j++){
if(G->acre[i][j]==1&&!visited[j]){
DFS(G,j);
}
}
}
void DFSTraveres(AdjMatrix *G){
int i;
for(i=0;i<G->vexnum;i++){
if(!visited[i]){ //對未訪問的點,進行DFS,如果是聯通圖,只會執行一次
DFS(G,i);
}
}
}
5.對鄰接表儲存的無向圖進行DFS
int visited[MAXVEX];
void DFS(AdjList *GL,int i){
ArcNode *p;
visited[i]=1;
printf("%c",GL->vertex[i].vexdata);
p=GL->vertex[i].head;
while(p){
if(!visited[p->adhVex]){
DFS(GL,p->adhVex);
}
p=p->next;
}
}
void DFSTraverse(AdjList *GL){
int i;
for(i=0;i<GL->vexnum;i++){
if(!visited[i]){
DFS(GL,i);
}
}
}
三. 廣度優先遍歷(BFS)
1.BFS的定義
圖的廣度優先遍歷BFS演算法是一個分層搜尋的過程,和樹的層序遍歷演算法類同,它也需要一個佇列以保持遍歷過的頂點順序,以便按出隊的順序再去訪問這些頂點的鄰接頂點。
2.遍歷思路
- 從圖中某個頂點V0出發,並訪問此頂點;
- 從V0出發,訪問V0的各個未曾訪問的鄰接點W1,W2,…,Wk;然後,依次從W1,W2,…,Wk出發訪問各自未被訪問的鄰接點;
- 重複步驟2,直到全部頂點都被訪問為止。
3.虛擬碼
(1) 初始化對列Q;visited[n]=0
(2) 訪問頂點v;visited[v]=1;頂點v入佇列Q;
(3)while(佇列Q非空){
v = 佇列的隊首元素出隊;
w = 頂點v的第一個鄰接點;
while(w存在){
如果w為訪問,則訪問頂點w;
visited[w]=1;
頂點w入佇列Q;
w=頂點v的下一個鄰接點.
}
}
4.對鄰接矩陣儲存無向圖的進行BFS
int visited[MAXSIZE];
void BFSTraveres(AdjMatrix *G){
int i,j;
CSeQeue *Q;//隊
Q=InitSeQueue();
for(i=0;i<G->vexnum;i++){
if(!visited[i]){ //對未訪問的點,進行DFS,如果是聯通圖,只會執行一次
visited[i]=1;
printf("%c",G->Vex[i]);
InSeQueue(Q,i);//入隊
while(!EmptySeQueue(Q)){ //如果當前隊不為空
QutSeQueue(Q,&i);//出隊
for(j=0;j<G->vexnum;j++){
if(G->acre[i][j]==1&&visited[j]==0){//如果鄰接點存在並未訪問過
visited[j]=1;
printf("%c",G->Vex[j]);
InSeQueue(Q,j);//入隊
}
}
}
}
}
}
5.對鄰接表儲存的無向圖進行BFS
int visited[MAXSIZE];
void BFSTraverse(AdjList *GL){
int i;
CSeQeue *Q;//隊
Q=InitSeQueue();
ArcNode *p;
for(i=0;i<GL->vexnum;i++){
if(!visited[i]){
visited[i]=1;
printf("%c",GL->vertex[i].vexdata);
InitSeQueue(Q,i);//入隊
while(!EmptySeQueue(Q)){
QutSeQueue(Q,&i);//出隊
p=GL->vertex[i].head;
while(p){
if(!visited[p->adhVex]){//節點未被訪問
visited[p->adhVex]=1;
printf("%c",GL->vertex[p->adhVex].vexdata);
InitSeQueue(Q,p->adhVex);//入隊
}
p=p->next;
}
}
}
}
}
四. 原始碼地址
五. 參考資料
《大話資料結構》
《資料結構與演算法》
華山大師兄部落格
相關推薦
資料結構18————圖的深度優先遍歷(DFS)&廣度優先遍歷(BFS)
資料結構18————圖的深度優先遍歷(DFS)&廣度優先遍歷(BFS) 一. 目錄 二. 深度優先遍歷(DFS) 1.DFS遞迴定義 假設給定圖的所有狀態都是未曾訪問過.在G中任選一個點V作為初始點。則深度優先遍歷的定義如下:
C++資料結構 23 圖-深度優先搜尋(DFS)
還是按鄰接矩陣的圖,使用深度優先搜尋(DFS:使用堆疊) #include <iostream> #include <stack> #define MAX_VERTS 20 using namespace std; /**使用鄰接矩陣來表示一個圖
《資料結構與演算法那》第七次 廣度、深度優先遍歷 圖及圖的遍歷(下)
《資料結構與演算法那》第七次課實驗內容 圖及圖的遍歷(下) 實驗目的: 熟悉圖的兩種儲存結構:鄰接矩陣和鄰接連結串列。 掌握在圖的鄰接表儲存結構上的遍歷演算法的實現。 實驗內容: 在已經開發好的c++類adjacencyGraph中,新增兩個成員函式,B
【資料結構】圖的深度優先遍歷 廣度優先遍歷
檔案操作比直接輸入方便許多 #include <stdio.h> #include <stdlib.h> #include <string.h> #define M 20 /*鄰接表的儲存結構*/ typedef struct node /
Java資料結構:圖的深度優先遍歷和廣度優先遍歷
更新啦,更新啦。 圖的深度優先遍歷:通過一個結點開始遍歷,直到遍歷到該結點沒有下一個結點為止,然後開始遞迴下一個結點,如果被訪問過,則跳過遍歷,依次類推。類似於一口氣到底,如果沒到底,則換個結點繼續到底。如果被訪問過的結點則不需要遍歷。 過程:A開始進入遞迴,A先列印。然後發現A的下一
資料結構--C語言--圖的深度優先遍歷,廣度優先遍歷,拓撲排序,用prime演算法實現最小生成樹,用迪傑斯特拉演算法實現關鍵路徑和關鍵活動的求解,最短路徑
實驗七 圖的深度優先遍歷(選做,驗證性實驗,4學時) 實驗目的 熟悉圖的陣列表示法和鄰接表儲存結構,掌握構造有向圖、無向圖的演算法 ,在掌握以上知識的基礎上,熟悉圖的深度優先遍歷演算法,並實現。 實驗內容 (1)圖的陣列表示法定義及
資料結構:圖的遍歷--深度優先、廣度優先
圖的遍歷:深度優先、廣度優先 遍歷 圖的遍歷是指從圖中的某一頂點出發,按照一定的策略訪問圖中的每一個頂點。當然,每個頂點有且只能被訪問一次。
資料結構之圖的深度優先遍歷和廣度優先遍歷
1.圖的簡單介紹 上圖就是一個圖(無線圖),由頂點和連線組成 圖可以分為無向圖和有向圖(這個又有出度、入度的概念)、網,一般來說圖有兩種常用的表示方式,鄰接矩陣(用二維陣列的形式表示)和鄰接表(主要是陣列+連結串列的形式表示),圖常用的遍歷方式有深度優先遍歷(DFS)和廣
資料結構---圖的鄰接表(建立、列印、深度優先遍歷,廣度優先遍歷C語言)
當一個圖為稀疏圖時,使用鄰接矩陣會浪費大量儲存空間。 鄰接表法結合了順序儲存和鏈式儲存方法,減少了不必要的浪費。 鄰接表 1)對圖G的每個頂點vi建立一個單鏈表,第i個單鏈表中的結點表示依附於頂點vi的邊(對於有向圖則是以頂點vi為尾的弧)。這個單鏈表就稱為頂點vi
【資料結構】圖(深度優先遍歷、廣度優先遍歷)的JAVA程式碼實現
圖的遍歷是指從圖中的任一頂點出發,對圖中的所有頂點訪問一次並且只訪問一次。圖的遍歷是圖的一種基本操作,圖中的許多其他操作也都是建立在遍歷的基礎之上。在圖中,沒有特殊的頂點被指定為起始頂點,圖的遍歷可以從任何頂點開始。圖的遍歷主要有深度優先搜尋和廣度優先搜尋兩種方式。深度優先搜
資料結構--圖--圖的陣列儲存表示,深度優先搜尋遍歷和廣度優先搜尋遍歷
圖有四種儲存結構:陣列,鄰接表,十字連結串列,鄰接多重表。下面以陣列為儲存結構來實現圖的深度優先搜尋遍歷和廣度優先搜尋遍歷。其中廣度優先搜尋遍歷中有用到STL中的queue,注意標頭檔案的包含。具體程式碼如下: //圖的陣列(鄰接矩陣)儲存表示和深度優先遍歷 co
小朋友學資料結構(16):基於鄰接矩陣的的深度優先遍歷和廣度優先遍歷
觀察下面兩個無向圖: 這兩個圖其實是一樣的,只是畫法不同罷了。第一張圖更有立體感,第二張圖更有層次感,並且把A點置為頂點(事實上圖的任何一點都可以做為頂點)。 一、用陣列來存放頂點 vexs[0] = ‘A’ vexs[1] = ‘B’ vexs[2] = ‘C’ ve
資料結構之圖篇(2):圖的基本操作 深度和廣度遍歷
程式碼實現 main.cpp(主函式) #include <iostream> #include "CMap.h" using namespace std; /** 圖的的儲存:鄰接矩陣 圖的遍歷:深度+廣度 A / \
C語言實現圖的鄰接矩陣儲存結構及深度優先遍歷和廣度優先遍歷
DFS的核心思想在於對訪問的鄰接節點進行遞迴呼叫;BFS的核心思想在於建立了一個鄰接節點的佇列。 在Dev C++中除錯執行通過。 用下圖進行了測試。 #include <stdio.h> #define MaxVertexNum 50 #defin
SDUT OJ 2413 資料結構實驗圖論一:基於鄰接矩陣的廣度優先搜尋遍歷
#include<iostream> #include<memory.h> using namespace std; int p[1010][1010]; int visit[110]; int c[1010]; int a=0; int b=
SDUTOJ 2141 ——資料結構實驗圖論一:基於鄰接矩陣的廣度優先搜尋遍歷
資料結構實驗圖論一:基於鄰接矩陣的廣度優先搜尋遍歷 Time Limit: 1000ms Memory limit: 65536K 有疑問?點這裡^_^ 題目描述 給定一個無向連通圖,頂點編號從0到n-1,用廣度優先搜尋(BFS)遍歷,輸出從某個
資料結構實驗圖論:基於鄰接矩陣/鄰接表的廣度優先搜尋遍歷(BFS)
//#include <iostream> //#include <stdlib.h> //#include <stdio.h> //#include <string.h> //#include <queue> //#define M 20 //#
SDUT 2141 資料結構實驗圖論一:基於鄰接矩陣的廣度優先搜尋遍歷
#include <bits/stdc++.h> using namespace std; bool vis[100]; int n, k, m, s, u, v; int Graph
sdut oj2141 資料結構實驗圖論一:基於鄰接矩陣的廣度優先搜尋遍歷(BFS)
資料結構實驗圖論一:基於鄰接矩陣的廣度優先搜尋遍歷 Time Limit: 1000MS Memory limit: 65536K 題目描述 給定一個無向連通圖,頂點編號從0到n-1,用廣度優先搜尋(BFS)遍歷,輸出從某個頂點出發的遍歷序列。(同一個結點的
資料結構實驗圖論:基於鄰接矩陣/鄰接表的廣度優先搜尋遍歷
資料結構實驗圖論一:基於鄰接矩陣的廣度優先搜尋遍歷 Time Limit: 1000ms Memory limit: 65536K 有疑問?點這裡^_^ 題目描述 給定一個無向連通圖,頂點編號從0到n-1,用廣度優先搜尋(BFS)遍歷,輸出從某個頂點出發的遍