1、 《数据结构》课程实验报告 题目:图遍历的演示 班级: 姓名: 学号: 专业: 学院: 完成日期: 一、 需求分析 (1) 问题描述: 很多涉及图上操作的算法都是以图的遍历操作作为基础的。试写一个程序,演示在连通图的无向图上访问全部结点的操作。 (2) 基本要求: 以邻接多重表(选作内容邻接表)为存储结构,实现连通无
2、向图的深度优先遍历和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集
(3) 输入的形式和输入的范围:先输入顶点数N以及边数M,然后依次输入N个顶点,再按提示输入M条边的信息用(a-b 3)类似的形式
(4) 测试数据:
教科书图7.33部分信息
二、 概要设计
(1) 抽象数据类型图的定义:
ADT Graph{
数据对象V:V是具有相同特性的的数据元素的集合,成为顶点集。
数据关系 R:
R={VR}
VR={
3、w є V且P(v,w),
4、atedg(& G); 初始条件:图G 存在。 操作结果:创建有向网。 DFS(G,v); 初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。 操作结果:深度优先搜索遍历图G,访问顶点时使用函数 visit. BFS(G,v); 初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。 操作结果:广度优先搜索遍历图G,访问顶点时使用函数 visit. visit( a); 初始条件:a为图中的某个顶点值。 操作结果:访问顶点a,本程序中作用结果为输出顶点值。 }ADT Graph (2) .邻接表存储结构的图定义:
5、ADT algraph{
数据对象V:V是具有相同特性的的数据元素的集合,成为顶点集。
数据关系 R:
R={VR}
VR={
6、 初始条件:图G 存在。 操作结果:创建有向图。 Createudg( & G); 初始条件:图G 存在。 操作结果:创建无向网。 createdg(& G); 初始条件:图G 存在。 操作结果:创建有向网。 DFS(G,v); 初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。 操作结果:深度优先搜索遍历图G,访问顶点时使用函数 visit. BFS(G,v); 初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。 操作结果:广度优先搜索遍历图G,访问顶点时使用函数visit. visit( a); 初
7、始条件:a为图中的某个顶点值。
操作结果:访问顶点a,本程序中作用结果为输出顶点值。 }ADT algraph
2. (3)设定队列的抽象数据类型定义:
ADT Queue{
数据对象:D={ai|ai∈ElemSet, i=1,2, …,n, n≥0}
数据关系:R1={
8、已存在。 操作结果:销毁队列Q。 ClearQueue ( &Q ) 初始条件:队列Q已存在。 操作结果:将Q清为空队列。 QueueEmpty( Q ) 初始条件:队列Q已存在。 操作结果:若Q为空队列,则返回TRUE,否则返回FALSE。 QueueLength( Q ) 初始条件:队列Q已存在。 操作结果:返回Q的数据元素个数,即队列的长度。 GetHead( Q, &e ) 初始条件:队列Q已存在且非空。 操作结果:用e返
9、回Q的队头元素。 EnQueue( &Q, e ) 初始条件:队列Q已存在。 操作结果:插入元素e为Q的新的队尾元素。 DeQueue( &Q, &e ) 初始条件:队列Q已存在且非空。 操作结果:删除Q的队头元素,并用e返回其值。 QueueTraverse( Q, visit() ) 初始条件:队列Q已存在且非空。 操作结果:从队头到队尾依次对Q的每个数据元素调用函数visit()。一旦visit()失败,则操作失败。 }ADT Queue 三、 详细设计 (1) 元素类型、
10、结点类型和指针类型 typedef struct{ //图的邻接矩阵存储结构 char *vexs; //顶点向量 int arcs[MAX+1][MAX+1]; //邻接矩阵 int vexnum,arcnum; //图的当前顶点数和边数 }Graph; (2) 队列的具体定义 class Queue{
11、 //队列类 public: void InitQueue() { base=(int *)malloc(QUEUE_SIZE*sizeof(int)); front=rear=0; } void EnQueue(int e){ //插入元素e为新的队尾元素 base[rear]=e; rear=(rear+1)%QUEUE_SIZE; //
12、rear后移 } void DeQueue(int &e){ //若队列不空,则删除对头元素,用e返回 e=base[front]; front=(front+1)%QUEUE_SIZE; } public: int *base; int front; int rear; }; (3) 查找定位函数 int Locate(Graph G,char c){ //图G中查找元素c的位置 for(int i=1;i<=G.vexn
13、um;i++){ if(G.vexs[i]==c) return i; } return -1; } (4) 初始化无向图函数 void CreateUDN(Graph &G){ //创建无向图 int i,j,w,s1,s2; char a,b,temp; cout<<"输入顶点的总数和边的总数:"; cin>>G.vexnum>>G.arcnum; temp=getchar();
14、 //接收回车
G.vexs=(char *)malloc(G.vexnum*sizeof(char)); //分配顶点数目
cout<<"输入"<
15、
for(i=1;i<=G.vexnum;i++) //初始化邻接矩阵
for(j=1;j<=G.vexnum;j++)
G.arcs[i][j]=INFINITY; //16int类型,初始化边为无穷大
cout<<"输入"< 16、1;i<=G.arcnum;i++){ //初始化边
cout<<"边"< 17、 } //无向
}
int FirstVex(Graph G,int k){ //图G中顶点k的第一个邻接顶点
if(k>=1 && k<=G.vexnum){
for(int i=1;i<=G.vexnum;i++)
if(G.arcs[k][i]!=INFINITY)
return i;
}
return -1;
}
int NextVex(Graph G,int i,int j){ //图 18、G中顶点i的第j个邻接顶点的下一个邻接顶点
if(i>=1 && i<=G.vexnum && j>=1 && j<=G.vexnum){ //i,j合理
for(int k=j+1;k<=G.vexnum;k++)
if(G.arcs[i][k]!=INFINITY)
return k;
}
return -1;
}
(5) 深度优先遍历及广度优先遍历函数
void DFS(Graph G,int k){ //深度优先搜索
19、 int i;
if(k==-1){ //第一次执行DFS时,k为-1
for(i=1;i<=G.vexnum;i++)
if(!visited[i])
DFS(G,i);
} //对尚未访问的顶点调用DFS
else{
visited[k]=true; //访问第k个顶点
20、 cout< 21、 //辅助队列Q
Q.InitQueue();
for(int i=0;i<=G.vexnum;i++)
if(!visited[i]){ //i尚未访问
visited[i]=true;
cout< 22、 //i入列
while(Q.front!=Q.rear){
Q.DeQueue(k); //队头元素出列并置为k
for(int w=FirstVex(G,k);w>=0;w=NextVex(G,k,w))
if(!visited[w]){ //w为k的尚未访 23、问的邻接顶点
visited[w]=true;
cout< 24、 //创建无向图
visited=(bool *)malloc(G.vexnum*sizeof(bool));
cout<






