图的遍历操作实验报告.docx
- 文档编号:28838456
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:22
- 大小:50.67KB
图的遍历操作实验报告.docx
《图的遍历操作实验报告.docx》由会员分享,可在线阅读,更多相关《图的遍历操作实验报告.docx(22页珍藏版)》请在冰豆网上搜索。
图的遍历操作实验报告
实验三、图的遍历操作
一、目的
掌握有向图和无向图的概念;掌握邻接矩阵和邻接链表建立图的存储结构;掌握DFS及BFS对图的遍历操作;了解图结构在人工智能、工程等领域的广泛应用。
二、要求
采用邻接矩阵和邻接链表作为图的存储结构,完成有向图和无向图的DFS和BFS操作。
三、DFS和BFS的基本思想
深度优先搜索法DFS的基本思想:
从图G中某个顶点Vo出发,首先访问Vo,然后选择一个与Vo相邻且没被访问过的顶点Vi访问,再从Vi出发选择一个与Vi相邻且没被访问过的顶点Vj访问,……依次继续。
如果当前被访问过的顶点的所有邻接顶点都已被访问,则回退到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样方法向前遍历。
直到图中所有的顶点都被访问。
广度优先算法BFS的基本思想:
从图G中某个顶点Vo出发,首先访问Vo,然后访问与Vo相邻的所有未被访问过的顶点V1,V2,……,Vt;再依次访问与V1,V2,……,Vt相邻的起且未被访问过的的所有顶点。
如此继续,直到访问完图中的所有顶点。
四、示例程序
1.邻接矩阵作为存储结构的程序示例
#include"stdio.h"
#include"stdlib.h"
#defineMaxVertexNum100//定义最大顶点数
typedefstruct{
charvexs[MaxVertexNum];//顶点表
intedges[MaxVertexNum][MaxVertexNum];//邻接矩阵,可看作边表
intn,e;//图中的顶点数n和边数e
}MGraph;//用邻接矩阵表示的图的类型
//=========建立邻接矩阵=======
voidCreatMGraph(MGraph*G)
{
inti,j,k;
chara;
printf("InputVertexNum(n)andEdgesNum(e):
");
scanf("%d,%d",&G->n,&G->e);//输入顶点数和边数
scanf("%c",&a);
printf("InputVertexstring:
");
for(i=0;i
{
scanf("%c",&a);
G->vexs[i]=a;//读入顶点信息,建立顶点表
}
for(i=0;i
for(j=0;j
G->edges[i][j]=0;//初始化邻接矩阵
printf("Inputedges,CreatAdjacencyMatrix\n");
for(k=0;k
scanf("%d%d",&i,&j);//输入边(Vi,Vj)的顶点序号
G->edges[i][j]=1;
G->edges[j][i]=1;//若为无向图,矩阵为对称矩阵;若建立有向图,去掉该条语句
}
}
//=========定义标志向量,为全局变量=======
typedefenum{FALSE,TRUE}Boolean;
Booleanvisited[MaxVertexNum];
//========DFS:
深度优先遍历的递归算法======
voidDFSM(MGraph*G,inti)
{//以Vi为出发点对邻接矩阵表示的图G进行DFS搜索,邻接矩阵是0,1矩阵
intj;
printf("%c",G->vexs[i]);//访问顶点Vi
visited[i]=TRUE;//置已访问标志
for(j=0;j
if(G->edges[i][j]==1&&!
visited[j])
DFSM(G,j);//(Vi,Vj)∈E,且Vj未访问过,故Vj为新出发点
}
voidDFS(MGraph*G)
{
inti;
for(i=0;i
visited[i]=FALSE;//标志向量初始化
for(i=0;i
if(!
visited[i])//Vi未访问过
DFSM(G,i);//以Vi为源点开始DFS搜索
}
//===========BFS:
广度优先遍历=======
voidBFS(MGraph*G,intk)
{//以Vk为源点对用邻接矩阵表示的图G进行广度优先搜索
inti,j,f=0,r=0;
intcq[MaxVertexNum];//定义队列
for(i=0;i
visited[i]=FALSE;//标志向量初始化
for(i=0;i
cq[i]=-1;//队列初始化
printf("%c",G->vexs[k]);//访问源点Vk
visited[k]=TRUE;
cq[r]=k;//Vk已访问,将其入队。
注意,实际上是将其序号入队
while(cq[f]!
=-1){//队非空则执行
i=cq[f];f=f+1;//Vf出队
for(j=0;j
if(G->edges[i][j]==1&&!
visited[j]){//Vj未访问
printf("%c",G->vexs[j]);//访问Vj
visited[j]=TRUE;
r=r+1;cq[r]=j;//访问过Vj入队
}
}
}
//==========main=====
voidmain()
{
inti;
MGraph*G;
G=(MGraph*)malloc(sizeof(MGraph));//为图G申请存空间
CreatMGraph(G);//建立邻接矩阵
printf("PrintGraphDFS:
");
DFS(G);//深度优先遍历
printf("\n");
printf("PrintGraphBFS:
");
BFS(G,3);//以序号为3的顶点开始广度优先遍历
printf("\n");
}
执行顺序:
InputVertexNum(n)andEdgesNum(e):
8,9
InputVertexstring:
01234567
Inputedges,CreatAdjacencyMatrix
01
02
13
14
25
26
37
47
56
PrintGraphDFS:
01374256
PrintGraphBFS:
31704256
2.邻接链表作为存储结构程序示例
#include"stdio.h"
#include"stdlib.h"
#defineMaxVertexNum50//定义最大顶点数
typedefstructnode{//边表结点
intadjvex;//邻接点域
structnode*next;//链域
}EdgeNode;
typedefstructvnode{//顶点表结点
charvertex;//顶点域
EdgeNode*firstedge;//边表头指针
}VertexNode;
typedefVertexNodeAdjList[MaxVertexNum];//AdjList是邻接表类型
typedefstruct{
AdjListadjlist;//邻接表
intn,e;//图中当前顶点数和边数
}ALGraph;//图类型
//=========建立图的邻接表=======
voidCreatALGraph(ALGraph*G)
{
inti,j,k;
chara;
EdgeNode*s;//定义边表结点
printf("InputVertexNum(n)andEdgesNum(e):
");
scanf("%d,%d",&G->n,&G->e);//读入顶点数和边数
scanf("%c",&a);
printf("InputVertexstring:
");
for(i=0;i
{
scanf("%c",&a);
G->adjlist[i].vertex=a;//读入顶点信息
G->adjlist[i].firstedge=NULL;//边表置为空表
}
printf("Inputedges,CreatAdjacencyList\n");
for(k=0;k
scanf("%d%d",&i,&j);//读入边(Vi,Vj)的顶点对序号
s=(EdgeNode*)malloc(sizeof(EdgeNode));//生成边表结点
s->adjvex=j;//邻接点序号为j
s->next=G->adjlist[i].firstedge;
G->adjlist[i].firstedge=s;//将新结点*S插入顶点Vi的边表头部
s=(EdgeNode*)malloc(sizeof(EdgeNode));
s->adjvex=i;//邻接点序号为i
s->next=G->adjlist[j].firstedge;
G->adjlist[j].firstedge=s;//将新结点*S插入顶点Vj的边表头部
}
}
//=========定义标志向量,为全局变量=======
typedefenum{FALSE,TRUE}Boolean;
Booleanvisited[MaxVertexNum];
//========DFS:
深度优先遍历的递归算法======
voidDFSM(ALGraph*G,inti)
{//以Vi为出发点对邻接链表表示的图G进行DFS搜索
EdgeNode*p;
printf("%c",G->adjlist[i].vertex);//访问顶点Vi
visited[i]=TRUE;//标记Vi已访问
p=G->adjlist[i].firstedge;//取Vi边表的头指针
while(p){//依次搜索Vi的邻接点Vj,这里j=p->adjvex
if(!
visited[p->adjvex])//若Vj尚未被访问
DFSM(G,p->adjvex);//则以Vj为出发点向纵深搜索
p=p->next;//找Vi的下一个邻接点
}
}
voidDFS(ALGraph*G)
{
inti;
for(i=0;i
visited[i]=FALSE;//标志向量初始化
for(i=0;i
if(!
visited[i])//Vi未访问过
DFSM(G,i);//以Vi为源点开始DFS搜索
}
//==========BFS:
广度优先遍历=========
voidBFS(ALGraph*G,intk)
{//以Vk为源点对用邻接链表表示的图G进行广度优先搜索
inti,f=0,r=0;
EdgeNode*p;
intcq[MaxVertexNum];//定义FIFO队列
for(i=0;i
visited[i]=FALSE;//标志向量初始化
for(i=0;i<=G->n;i++)
cq[i]=-1;//初始化标志向量
printf("%c",G->adjlist[k].vertex);//访问源点Vk
visited[k]=TRUE;
cq[r]=k;//Vk已访问,将其入队。
注意,实际上是将其序号入队
while(cq[f]!
=-1){队列非空则执行
i=cq[f];f=f+1;//Vi出队
p=G->adjlist[i].firstedge;//取Vi的边表头指针
while(p){//依次搜索Vi的邻接点Vj(令p->adjvex=j)
if(!
visited[p->adjvex]){//若Vj未访问过
printf("%c",G->adjlist[p->adjvex].vertex);//访问Vj
visited[p->adjvex]=TRUE;
r=r+1;cq[r]=p->adjvex;//访问过的Vj入队
}
p=p->next;//找Vi的下一个邻接点
}
}//endwhile
}
//==========主函数===========
voidmain()
{
inti;
ALGraph*G;
G=(ALGraph*)malloc(sizeof(ALGraph));
CreatALGraph(G);
printf("PrintGraphDFS:
");
DFS(G);
printf("\n");
printf("PrintGraphBFS:
");
BFS(G,3);
printf("\n");
}
执行顺序:
InputVertexNum(n)andEdgesNum(e):
8,9
InputVertexstring:
01234567
Inputedges,CreatAdjacencyList
01
02
13
14
25
26
37
47
56
PrintGraphDFS:
02651473
PrintGraphBFS:
37140265
五、修改后的代码
1.邻接矩阵作为存储结构的程序
#include"stdio.h"
#include"stdlib.h"
#defineMaxVertexNum100//定义最大顶点数
typedefstruct{
charvexs[MaxVertexNum];//顶点表
intedges[MaxVertexNum][MaxVertexNum];//邻接矩阵,可看作边表
intn,e;//图中的顶点数n和边数e
}MGraph;//用邻接矩阵表示的图的类型
//=========建立邻接矩阵=======
voidCreatMGraph(MGraph*G)
{
inti,j,k;
chara;
printf("InputVertexNum(n)andEdgesNum(e):
");
scanf("%d,%d",&G->n,&G->e);//输入顶点数和边数
scanf("%c",&a);
printf("InputVertexstring:
");
for(i=0;i
{
scanf("%c",&a);
G->vexs[i]=a;//读入顶点信息,建立顶点表
}
for(i=0;i
for(j=0;j
G->edges[i][j]=0;//初始化邻接矩阵
printf("Inputedges,CreatAdjacencyMatrix\n");
for(k=0;k
scanf("%d%d",&i,&j);//输入边(Vi,Vj)的顶点序号
G->edges[i][j]=1;
G->edges[j][i]=1;//若为无向图,矩阵为对称矩阵;若建立有向图,去掉该条语句
}
}
//=========定义标志向量,为全局变量=======
typedefenum{FALSE,TRUE}Boolean;
Booleanvisited[MaxVertexNum];
//========DFS:
深度优先遍历的递归算法======
voidDFSM(MGraph*G,inti)
{//以Vi为出发点对邻接矩阵表示的图G进行DFS搜索,邻接矩阵是0,1矩阵
intj;
printf("%c",G->vexs[i]);//访问顶点Vi
visited[i]=TRUE;//置已访问标志
for(j=0;j
if(G->edges[i][j]==1&&!
visited[j])
DFSM(G,j);//(Vi,Vj)∈E,且Vj未访问过,故Vj为新出发点
}
voidDFS(MGraph*G)
{
inti;
for(i=0;i
visited[i]=FALSE;//标志向量初始化
for(i=0;i
if(!
visited[i])//Vi未访问过
DFSM(G,i);//以Vi为源点开始DFS搜索
}
//===========BFS:
广度优先遍历=======
voidBFS(MGraph*G,intk)
{//以Vk为源点对用邻接矩阵表示的图G进行广度优先搜索
inti,j,f=0,r=0;
intcq[MaxVertexNum];//定义队列
for(i=0;i
visited[i]=FALSE;//标志向量初始化
for(i=0;i
cq[i]=-1;//队列初始化
printf("%c",G->vexs[k]);//访问源点Vk
visited[k]=TRUE;
cq[r]=k;//Vk已访问,将其入队。
注意,实际上是将其序号入队
while(cq[f]!
=-1){//队非空则执行
i=cq[f];f=f+1;//Vf出队
for(j=0;j
if(G->edges[i][j]==1&&!
visited[j]){//Vj未访问
printf("%c",G->vexs[j]);//访问Vj
visited[j]=TRUE;r=r+1;cq[r]=j;//访问过Vj入队
}
}
}
//==========main=====
voidmain()
{
MGraph*G;
G=(MGraph*)malloc(sizeof(MGraph));//为图G申请存空间
CreatMGraph(G);//建立邻接矩阵
printf("PrintGraphDFS:
");
DFS(G);//深度优先遍历
printf("\n");
printf("PrintGraphBFS:
");
BFS(G,3);//以序号为3的顶点开始广度优先遍历
printf("\n");
}
2.邻接链表作为存储结构程序
#include"stdio.h"
#include"stdlib.h"
#defineMaxVertexNum50//定义最大顶点数
typedefstructnode{//边表结点
intadjvex;//邻接点域
structnode*next;//链域
}EdgeNode;
typedefstructvnode{//顶点表结点
charvertex;//顶点域
EdgeNode*firstedge;//边表头指针
}VertexNode;
typedefVertexNodeAdjList[MaxVertexNum];//AdjList是邻接表类型
typedefstruct{
AdjListadjlist;//邻接表
intn,e;//图中当前顶点数和边数
}ALGraph;//图类型
//=========建立图的邻接表=======
voidCreatALGraph(ALGraph*G)
{
inti,j,k;
chara;
EdgeNode*s;//定义边表结点
printf("InputVertexNum(n)andEdgesNum(e):
");
scanf("%d,%d",&G->n,&G->e);//读入顶点数和边数
scanf("%c",&a);
printf("InputVertexstring:
");
for(i=0;i
{
scanf("%c",&a);
G->adjlist[i].vertex=a;//读入顶点信息
G->adjlist[i].firstedge=NULL;//边表置为空表
}
printf("Inputedges,CreatAdjacencyList\n");
for(k=0;k
scanf("%d%d",&i,&j);//读入边(Vi,Vj)的顶点对序号
s=(EdgeNode*)malloc(sizeof(EdgeNode));//生成边表结点
s->adjvex=j;//邻接点序号为j
s->next=G->adjlist[i].firstedge;
G->adjlist[i].firstedge=s;//将新结点*S插入顶点Vi的边表头部
s=(EdgeNode*)malloc(sizeof(EdgeNode));
s->adjvex=i;//邻接点序号为i
s->next=G->adjlist[j].firstedge;
G->adjlist[j].firstedge=s;//将新结点*S插入顶点Vj的边表头部
}
}
//=========定义标志向量,为全局变量=======
typedefenum{FALSE,TRUE}Boolean;
Booleanvisited[MaxVertexNum];
//========DFS:
深度优先遍历的递归算法======
voidDFSM(ALGraph*G,inti)
{//以Vi为出发点对邻接链表表示的图G进行DFS搜索
EdgeNode*p;
printf("%c",G->adjlist[i].vertex);//访问顶点Vi
visited[i]=TRUE;//标记Vi已访问
p=G->adjlist[i].firstedge;//取Vi边表的头指针
while(p){//依次搜索Vi的邻接点Vj,这里j=p->adjvex
if(!
visited[p->adjvex])//若Vj尚未被访问
DFSM(G,p->adjvex);//则以Vj为出发点向纵深搜索
p=p->next;//找Vi的下一个邻接点
}
}
voidDFS(ALGraph*G)
{
inti;
f
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 遍历 操作 实验 报告