檢驗深度優先和廣度優先的程序(鄰接表存儲結構)

圖有2 個基本操作:FirstAdjVex(G,v)和NextAdjVex(G,v,w)。FirstAdjVex(G,v)返回
圖G 中頂點v 的第1 個鄰接頂點(在圖中的位置)。在鄰接矩陣存儲結構中,返回鄰接矩陣

G.arcs.adj 中v 所對應的行的第1 個值爲1(圖)或權值(網)的頂點(在圖中的位置)。以f7-

1.txt 所表示的圖G 爲例,FirstAdjVex(G,a)(在bo7-1.cpp 中)返回b 在圖中的位置1;
FirstAdjVex(G,e)返回a 在圖中的位置0。NextAdjVex(G,v,w)比FirstAdjVex(G,v)多了1
個形參w,它返回圖G 中頂點v 的所有鄰接頂點中排在鄰接頂點w 後面的那個鄰接頂點
(在圖中的位置)。在鄰接矩陣存儲結構中,返回鄰接矩陣G.arcs.adj 中v 所對應的行的w
那列後面的第1 個值爲1(圖)或權值(網)的頂點(在圖中的位置)。以f7-1.txt 所表示的圖
G 爲例,NextAdjVex(G,a,c)(在bo7-1.cpp 中)返回第1 行(a 行)排在第3 列(c 列)後面的
第1 個值爲1 的頂點e 在圖中的位置4。由這樣的定義,我們可以推知,algo7-10.cpp 調
用算法7.4 和7.5 對圖G 深度優先搜索的過程:首先訪問G 的第1 個頂點a;接下來訪問
a 的第1 個鄰接頂點b;再準備訪問b 的第1 個鄰接頂點a,但a 已被訪問過,則不再訪問
a,轉而訪問b 排在a 後的鄰接頂點d;再準備訪問d 的第1 個鄰接頂點b,由於同樣的原
因,轉而訪問b 排在d 後的鄰接頂點h;再訪問h 的第1 個未被訪問的鄰接頂點c、c 的第
1 個未被訪問的鄰接頂點g、g 的第1 個未被訪問的鄰接頂點f、f 的第1 個未被訪問的鄰接
頂點e。遍歷結束,其順序與程序運行結果相同。
algo7-10.cpp 調用算法7.6 對圖G 廣度優先搜索的過程(這時e 已被改爲E,a—b 邊
已被刪除,b 不再是a 的鄰接頂點):首先訪問G 的第1 個頂點a,將a 入隊,在隊不空的
情況下,出隊元素a,依次訪問a 的所有鄰接頂點c、E、f、g、h,並將它們入隊;依次出
隊c、E,訪問E 的鄰接頂點b,將b 入隊;依次出隊f、g、h,訪問h 的鄰接頂點d。遍
歷結束,其順序與程序運行結果相同。
algo7-11.cpp 是在鄰接表的存儲結構下,對圖G 深度優先搜索和廣度優先搜索的程
序。其中,不僅調用基於基本操作的算法7.4、7.5 和7.6,對圖G 深度優先搜索和廣度
優先搜索,而且,調用了基於鄰接表的存儲結構的對圖G 深度優先搜索和廣度優先搜索的
函數DFSTraverse1()和BFSTraverse1()。

// algo7-11.cpp 檢驗深度優先和廣度優先的程序(鄰接表存儲結構)
#include"c1.h"
#define MAX_NAME 5 // 頂點字符串的最大長度+1
typedef int InfoType; // 網的權值類型
typedef char VertexType[MAX_NAME]; // 頂點類型爲字符串
#include"c7-21.h" // 鄰接表存儲結構
#include"bo7-2.cpp" // 鄰接表存儲結構的基本操作
void visit(char *i)
{
	printf("%s ",i);
}
void main()
{
	ALGraph g;
	CreateGraphF(g); // 利用數據文件創建無向圖,在bo7-2.cpp中
	Display(g); // 輸出無向圖,在bo7-2.cpp中
	printf("深度優先搜索的結果:\n");
	DFSTraverse(g,visit); // 調用算法7.4,在bo7-2.cpp中
	DFSTraverse1(g,visit); // 另一種方法,在bo7-2.cpp中
	printf("廣度優先搜索的結果:\n");
	BFSTraverse(g,visit); // 調用算法7.6,在bo7-2.cpp中
	BFSTraverse1(g,visit); // 另一種方法,在bo7-2.cpp中
	DestroyGraph(g); // 銷燬圖g
}

代碼的運行結果:

請輸入數據文件名(f7-1.txt或f7-2.txt):f7-1.txt
請輸入圖的類型(有向圖:0,有向網:1,無向圖:2,無向網:3): 2
無向圖
8個頂點:
a b c d e f g h
14條弧(邊):
a→h a→g a→f a→e a→c a→b
b→h b→e b→d
c→h c→g
d→h
e→f
f→g
深度優先搜索的結果:
a h d b e f g c
a h d b e f g c
廣度優先搜索的結果:
a h g f e c b d
a h g f e c b d


algo7-11.cpp 和algo7-10.cpp 一樣,都是利用數據文件f7-1.txt 構造圖的。它們構造
的圖的拓撲結構完全相同,如圖748 所示,但它們的深度優先搜索卻並不同。這是因爲
雖然在它們的存儲結構中頂點序號是相同的,但由於鄰接表結構在構造邊時,總是將鄰接
頂點插在表頭,這樣,邊的輸入順序不同,圖的存儲結構也就不同。相對於某一頂點,它
的“第1 個鄰接頂點”、“下1 個鄰接頂點”也不同,這導致了搜索順序不同。
algo7-11.cpp 利用數據文件f7-1.txt 構造的無向圖G 的存儲結構如圖749 所示(略
去網的權值指針域,且爲直觀,用頂點名稱代替頂點位置)。根據這樣的存儲結構,
FirstAdjVex(G,a)(在bo7-2.cpp 中)返回h 在圖中的位置7;NextAdjVex(G,a,c)(在
bo7-2.cpp 中)返回b 在圖中的位置1。這樣,我們可以推知,algo7-11.cpp 調用算法7.4
和7.5 對圖G 深度優先搜索的過程:首先訪問G 的第1 個頂點a;接下來訪問a 的第1 個
鄰接頂點h;再訪問h 的第1 個鄰接頂點d;再準備訪問d 的第1 個鄰接頂點h,由於h 已
被訪問,轉而訪問d 排在h 後的鄰接頂點b;再訪問b 的第1 個未被訪問的鄰接頂點e、e
的第1 個未被訪問的鄰接頂點f、f 的第1 個未被訪問的鄰接頂點g、g 的第1 個未被訪問
的鄰接頂點c。遍歷結束,其順序與程序運行結果相同。algo7-11.cpp 調用算法7.6 對圖
G 廣度優先搜索的過程:首先訪問G 的第1 個頂點a;接下來依次訪問a 的所有鄰接頂點
h、g、f、e、c 和b;再訪問h 的鄰接頂點d。遍歷結束,其順序與程序運行結果相同。
DFSTraverse1() 和BFSTraverse1() 沒有調用圖的基本操作函數FirstAdjVex() 和

NextAdjVex(),它們直接用表結點的指針p,用p=G.vertices[v].firstarc 和p=p->next 代替
FirstAdjVex()和NextAdjVex()的作用。這樣做效率高、直觀,但僅適用於鄰接表存儲結
構。它們得到的結果是一樣的。



代碼的運行結果:

請輸入數據文件名(f7-1.txt或f7-2.txt):f7-2.txt
請輸入圖的類型(有向圖:0,有向網:1,無向圖:2,無向網:3): 2
無向圖
8個頂點:
a b c d e f g h
14條弧(邊):
a→b a→c a→e a→f a→g a→h
b→d b→e b→h
c→g c→h
d→h
e→f
f→g
深度優先搜索的結果:
a b d h c g f e
a b d h c g f e
廣度優先搜索的結果:
a b c e f g h d
a b c e f g h d

其中,深度優先搜索的順序與algo7-10.cpp 的一樣。algo7-10.cpp 利用數據文件
f7-2.txt 的運行結果與利用f7-1.txt 的一樣,讀者可自行驗證。
除了c7-1.h 存儲結構,c7-2.h~c7-4.h 中邊或弧都是以鏈表形式存儲的,且邊或弧
總是插在表頭。當邊或弧的輸入順序不同時,其存儲結構就不同,故搜索的順序不同。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章