数据结构课程实验图的存储与遍历.docx
《数据结构课程实验图的存储与遍历.docx》由会员分享,可在线阅读,更多相关《数据结构课程实验图的存储与遍历.docx(7页珍藏版)》请在冰豆网上搜索。
![数据结构课程实验图的存储与遍历.docx](https://file1.bdocx.com/fileroot1/2022-11/16/327fc58e-4c7f-4715-8df9-609f158cc7d5/327fc58e-4c7f-4715-8df9-609f158cc7d51.gif)
数据结构课程实验图的存储与遍历
实验五图的存储与遍历
1、实验目的
掌握图这种复杂的非线性结构的邻接矩阵和邻接表的存储表示,以及在此两种常用存储方式下深度优先遍历(dfs)和广度优先遍历(BFS)操作的实现。
2、实验预备知识
(1)图的存储结构:
邻接矩阵表示法和邻接表表示法。
邻接矩阵表示法除了要用一个二维数组存储用于表示顶点间相邻关系的邻接矩阵外,还需用一个一维数组来存储顶点信息,另外还有图的顶点数和边数。
邻接表表示法类似于树的孩子链表表示法。
(2)图的遍历方法有深度优先遍历(Depth-FirstTraersal)和广度优先遍历(Breadth-FirstTraversal),简称DFS和BFS。
DFS对图遍历时尽可能先对纵深方向进行搜索;BFS是类似于树的按层次遍历。
3、实验内容
题目1对以邻接矩阵为存储结构的图进行DFS和BFS遍历
(1)问题描述:
以邻接矩阵为图的存储结构,实现图的DFS和BFS遍历。
(2)基本要求:
建立一个图的邻接矩阵表示,输出顶点的一种DFS和BFS序列。
(3)测试数据:
如图4.18所示。
(4)实现提示:
图的DFS遍历可通过递归调用或用栈来实现。
其思想是:
只要当前结点未访问过,就访问该结点,沿着其一条分支深入下去,每深入一个未访问过的结点,就访问这个结点,然后从这个结点继续进行DFS遍历。
在这一过程中,若深入时遇到一个已访问过的结点,则查找是否有与这个结点相邻的下一个未访问过的结点。
若有则继续深人,否则将退回到这个结点的前一个结点,再找下一个相邻的本访问过的结点,……如此进行下去,直到所有的结点都被访问过。
BFS遍历可利用队列来帮助实现,也可以用栈。
实现方法与二叉树的层次遍历类似。
题目2对以邻接表为存储结构的图进行DFS和BFS遍历
(1)问题描述:
以邻接表为存储结构,实现图的DFS和BFS遍历。
(2)基本要求:
建立一个图的邻接表存储,输出顶点的一种DFS和BFS序列。
(3)测试数据:
如图4.19所示:
(4)实现提示:
以邻接表为存储结构的图的DFS和BFS算法的实现思想与以邻接矩阵为存储结构的实现是一样的。
只是由于图的存储形式不同。
而具体到取第一个邻接点和下一个邻接点的语句表示上有所差别而已。
4、实验步骤
(1)仔细分析实验内容,给出其算法和流程图;
(2)用C语言实现该算法;
(3)给出测试数据,并分析其结果;
(4)在实验报告册上写出实验过程。
5、实验报告要求
实验报告要求书写整齐,步骤完整,实验报告格式如下:
1、[实验目的]
2、[实验设备]
3、[实验步骤]
4、[实验内容]
5、[实验结果(结论)]
程序如下:
/*sy41.c*/
#defineMaxVertexNum10//设最大顶点数为10
#include
#include
typedefcharVertexType;
typedefintEdgeType;
typedefstruct{
charvexs[10];
intedges[10][10];
intn,e;
}MGraph;
#defineFALSE0
#defineTRUE1
#defineErrorprintf
intvisited[10];
voidCreateMGraph(MGraph*G);
voidDFSTraverseM(MGraph*G);
voidBFSTraverseM(MGraph*G);
voidDFSM(MGraph*G,inti);
voidBFSM(MGraph*G,inti);
#defineQueueSize30/*假定预分配的队列空间最多为30*/
typedefintDataType;/*队列中的元素类型为字符型*/
typedefstruct{
intfront;/*队头指针,队非空时指向队头元素*/
intrear;/*队尾指针,队非空时指向队尾元素的下一位置*/
intcount;/*计数器,记录队中元素总数*/
DataTypedata[QueueSize];
}CirQueue;
voidInitQueue(CirQueue*Q)/*初始队列*/
{Q->front=Q->rear=0;
Q->count=0;
}
intQueueEmpty(CirQueue*Q)/*判队空*/
{returnQ->count==0;
}
intQueueFull(CirQueue*Q)/*判队满*/
{returnQ->count==QueueSize;
}
voidEnQueue(CirQueue*Q,DataTypex)/*入队*/
{if(QueueFull(Q))
Error("Queueoverflow");/*队满上溢*/
else{Q->count++;/*队列元素个数加1*/
Q->data[Q->rear]=x;/*新元素插入队列*/
Q->rear=(Q->rear+1)%QueueSize;/*循环队列的尾指针加1*/
}
}
DataTypeDeQueue(CirQueue*Q)/*出队*/
{DataTypetemp;
if(QueueEmpty(Q))
Error("Queueunderflow");/*队空下溢*/
else{temp=Q->data[Q->front];
Q->count--;/*队列元素个数减1*/
Q->front=(Q->front+1)%QueueSize;/*循环队列的头指针加1*/
returntemp;
}
}
main()
{MGraph*G;/*定义一个以邻接矩阵为存储类型的图G*/
charch1,ch2;
printf("creategraph(adjoiningmatrix):
\n");/*创建图G的存储*/
CreateMGraph(G);
ch1='y';
while(ch1=='y'||ch1=='Y')
{printf("select:
\n");
printf("\nA----------------updategraph(adjoiningmatrix)");
printf("\nB----------------DegreeFirstsearch");
printf("\nC----------------breadthFirstsearch");
printf("\nD------------------exit\n");
scanf("\n%c",&ch2);
switch(ch2)
{case'A':
case'a':
CreateMGraph(G);
printf("creategraphsuccess。
\n");
break;
case'B':
case'b':
DFSTraverseM(G);break;
case'C':
case'c':
BFSTraverseM(G);break;
case'D':
case'd':
ch1='n';break;
default:
ch1='n';
}
}
}
voidCreateMGraph(MGraph*G)
{/*建立有向图G的邻接矩阵存储*/
inti,j,k,w;
charch;
printf("inputvertexnumberandedgenumber(inputformat:
vn,en):
\n");/*输入顶点数和边数,输入格式:
顶点数,边数*/
scanf("%d,%d",&(G->n),&(G->e));
printf("inputvertex(inputformat:
serialnumber):
\n");/*输入顶点信息,建立顶点表,输入格式为:
顶点号)/*/
for(i=0;in;i++)
scanf("%c",&(G->vexs[i]));
for(i=0;in;i++)
for(j=0;jn;j++)
G->edges[i][j]=0;/*初始化邻接矩阵*/
printf("inputedge(format:
i,j):
\n");/*输入e条边,输入格式为:
i,j*/
for(k=0;ke;k++)
{scanf("%d,%d",&i,&j);/*输入e条边,建立邻接矩阵*/
G->edges[i][j]=1;
}
}/*CreateMGraph*/
voidDFSTraverseM(MGraph*G)
{/*深度优先遍历以邻接矩阵存储的图G*/
inti;
printf("DegreeFirstsearch\n");
for(i=0;in;i++)
visited[i]=FALSE;/*标志向量初始化*/
for(i=0;in;i++)
if(!
visited[i])DFSM(G,i);/*Vi未访问过,以Vi为原点开始DFS搜索*/
}/*DFSTraverse*/
voidDFSM(MGraph*G,inti)
{/*以Vi为出发点,对邻接矩阵存储的图G进行DFS搜索*/
intj;
printf("vertex:
V%c\n",G->vexs[i]);/*访问顶点Vi*/
visited[i]=TRUE;
for(j=0;jn;j++)/*依次搜索Vi的邻接点*/
if(G->edges[i][j]==1&&!
visited[j])
DFSM(G,j);/*当∈E,且Vj未访问过时,以Vj为新的出发点继续按深度优先遍历*/
}/*DFSM*/
voidBFSTraverseM(MGraph*G)
{/*广度优先遍历邻接矩阵存储的图G*/
inti;
printf("breadthFirstsearch\n");
for(i=0;in;i++)
visited[i]=FALSE;/*标志向量初始化*/
for(i=0;in;i++)
if(!
visited[i])BFSM(G,i);/*Vi未访问过,以Vi为原点开始BFS搜索*/
}/*BFSTraverseM*/
voidBFSM(MGraph*G,intk)
{/*以Vi为出发点,对邻接矩阵存储的图G进行BFS搜索*/
inti,j;
CirQueueQ;
InitQueue(&Q);
printf("vertex:
v%c\n",G->vexs[k]);
visited[k]=TRUE;
EnQueue(&Q,k);/*原点Vk入队列*/
while(!
QueueEmpty(&Q))
{i=DeQueue(&Q);/*Vi出队列*/
for(j=0;jn;j++)/*依次搜索Vi的邻接点Vj*/
if(G->edges[i][j]==1&&!
visited[j])
{printf("vertex:
v%c\n",G->vexs[j]);
visited[j]=TRUE;
EnQueue(&Q,j);/*访问过的Vj入队列*/
}
}
}/*BFSM*/