检验深度优先和广度优先的程序(邻接表存储结构)

图有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 中边或弧都是以链表形式存储的,且边或弧
总是插在表头。当边或弧的输入顺序不同时,其存储结构就不同,故搜索的顺序不同。


posted @ 2014-08-29 21:24  meiyouor  阅读(491)  评论(0编辑  收藏  举报