有向图的深度和广度遍历.docx
《有向图的深度和广度遍历.docx》由会员分享,可在线阅读,更多相关《有向图的深度和广度遍历.docx(14页珍藏版)》请在冰豆网上搜索。
有向图的深度和广度遍历
青岛理工大学
数据结构课程实验报告
课程名称
数据结构
班级
实验日期
2012.5.10
姓名
实验成绩
实验名称
有向图的深度和广度遍历
实
验
目
的
及
要
求
实验目的:
1.学会建立有向图,掌握图的存储结构:
邻接表。
2.掌握图的两种遍历方法:
深度遍历和广度遍历。
实
验
环
境
硬件平台:
普通的PC机
软件平台:
Windows7操作系统
编程环境:
VisualC++
实
验
内
容
1.建立图;
2.利用邻接表,队列存储图的结构;
3.进行图的深度和广度遍历。
算
法
描
述
及
实
验
步
骤
//定义存储结构的结构体
typedefstructArcNode
{
intadjvex;
structArcNode*nextarc;
}ArcNode;
typedefstruct
{
VertexTypedata;
ArcNode*firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;
}ALGraph;//图的结构体
typedefintQElemType;
typedefstructQNode
{
QElemTypedata;
QNode*next;
}QNode,*QueuePtr;//队列的结点结构和指向它的指针
typedefstructLinkQueue
{
QueuePtrfront,rear;
}LinkQueue;//队列的结构体
intLocateVex(ALGraphG,VertexTypeu)//找出下标
{
inti;
for(i=1;i<=G.vexnum;++i)
if(u==G.vertices[i].data)
returni;
return0;
}
voidCreateGraph(ALGraph&G)//建立图
{
inti,j,k;
ArcNode*p;
VertexTypeva,vb;
printf("请输入图的顶点数,边数:
");
scanf("%d,%d",&G.vexnum,&G.arcnum);
printf("请输入%d个顶点的值:
\n",G.vexnum);
for(i=1;i<=G.vexnum;++i)
{
scanf("%d",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;
}
for(k=1;k<=G.arcnum;++k)
{
printf("请输入第%d条弧(边)的弧尾和弧头:
\n",k);
scanf("%d%d",&va,&vb);
i=LocateVex(G,va);
j=LocateVex(G,vb);
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
}}
voidDFS(ALGraphG,intv)//深度遍历逐步找到其中结点
{intw;
visited[v]=1;
printf("%d",G.vertices[v].data);
for(w=FirstAdjVex(G,G.vertices[v].data);w>=1;w=NextAdjVex(G,G.vertices[v].data,G.vertices[w].data))
if(!
visited[w])
DFS(G,w);
}
voidDFSTraverse(ALGraphG)//深度遍历
{
intv;
for(v=1;v<=G.vexnum;v++)
visited[v]=0;
for(v=1;v<=G.vexnum;v++)
if(!
visited[v])
DFS(G,v);
printf("\n");
}
voidBFSTraverse(ALGraphG)//广度遍历,利用队列
{
intv,u,w;
LinkQueueQ;
for(v=1;v<=G.vexnum;++v)
visited[v]=0;
InitQueue(Q);
for(v=1;v<=G.vexnum;v++)
if(!
visited[v])
{
visited[v]=1;
printf("%d",G.vertices[v].data);
EnQueue(Q,v);
while(!
QueueEmpty(Q))
{
DeQueue(Q,u);
for(w=FirstAdjVex(G,G.vertices[u].data);w>=1;w=NextAdjVex(G,G.vertices[u].data,G.vertices[w].data))
if(!
visited[w])
{
visited[w]=1;
printf("%d",G.vertices[w].data);
EnQueue(Q,w);
}}}
printf("\n");
}
调
试
过
程
及
实
验
结
果
总
结
编程心得:
1.对基础知识的掌握一定要牢固,熟练掌握队列的操作
2.熟练掌握邻接表的结构体
3.熟悉各种操作的算法,根据思路做题。
附
录
#include
#include
#include
#include
#include
#defineINFEASIBLE-1
typedefintStatus;
typedefintBoolean;
#defineMAX_VERTEX_NUM21
#defineNULL0
typedefintVertexType;
typedefstructArcNode
{
intadjvex;
structArcNode*nextarc;
}ArcNode;
typedefstruct
{
VertexTypedata;
ArcNode*firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;
}ALGraph;
intLocateVex(ALGraphG,VertexTypeu)
{
inti;
for(i=1;i<=G.vexnum;++i)
if(u==G.vertices[i].data)
returni;
return0;
}
voidCreateGraph(ALGraph&G)
{
inti,j,k;
ArcNode*p;
VertexTypeva,vb;
printf("请输入图的顶点数,边数:
");
scanf("%d,%d",&G.vexnum,&G.arcnum);
printf("请输入%d个顶点的值:
\n",G.vexnum);
for(i=1;i<=G.vexnum;++i)
{
scanf("%d",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;
}
for(k=1;k<=G.arcnum;++k)
{
printf("请输入第%d条弧(边)的弧尾和弧头:
\n",k);
scanf("%d%d",&va,&vb);
i=LocateVex(G,va);
j=LocateVex(G,vb);
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
}
for(i=1;i<=G.vexnum;i++)
{
printf("\n%d的邻接顶点:
",G.vertices[i].data);
ArcNode*p;
p=G.vertices[i].firstarc;
while(p)
{
printf("%d",G.vertices[p->adjvex].data);
p=p->nextarc;
}
if(i==G.vexnum)
printf("\n");
}
}
intFirstAdjVex(ALGraphG,VertexTypev)
{
ArcNode*p;
intv1;
v1=LocateVex(G,v);
p=G.vertices[v1].firstarc;
if(p)
returnp->adjvex;
else
return0;
}
intNextAdjVex(ALGraphG,VertexTypev,VertexTypew)
{
ArcNode*p;
intv1,w1;
v1=LocateVex(G,v);
w1=LocateVex(G,w);
p=G.vertices[v1].firstarc;
while(p&&p->adjvex!
=w1)
p=p->nextarc;
if(!
p||!
p->nextarc)return0;
else
returnp->nextarc->adjvex;
}
Booleanvisited[MAX_VERTEX_NUM];
voidDFS(ALGraphG,intv)
{
intw;
visited[v]=1;
printf("%d",G.vertices[v].data);
for(w=FirstAdjVex(G,G.vertices[v].data);w>=1;w=NextAdjVex(G,G.vertices[v].data,G.vertices[w].data))
if(!
visited[w])
DFS(G,w);
}
voidDFSTraverse(ALGraphG)
{
intv;
for(v=1;v<=G.vexnum;v++)
visited[v]=0;
for(v=1;v<=G.vexnum;v++)
if(!
visited[v])
DFS(G,v);
printf("\n");
}
typedefintQElemType;
typedefstructQNode
{
QElemTypedata;
QNode*next;
}QNode,*QueuePtr;
typedefstructLinkQueue
{
QueuePtrfront,rear;
}LinkQueue;
voidInitQueue(LinkQueue&Q)
{
if(!
(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))
exit(OVERFLOW);
Q.front->next=NULL;
}
voidDestroyQueue(LinkQueue&Q)
{
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
}
voidClearQueue(LinkQueue&Q)
{
QueuePtrp,q;
Q.rear=Q.front;
p=Q.front->next;
Q.front->next=NULL;
while(p)
{
q=p;
p=p->next;
free(q);
}
}
StatusQueueEmpty(LinkQueueQ)
{
if(Q.front->next==NULL)
return1;
else
return0;
}
intQueueLength(LinkQueueQ)
{
inti=0;
QueuePtrp;
p=Q.front;
while(Q.rear!
=p)
{
i++;
p=p->next;
}
returni;
}
StatusGetHead(LinkQueueQ,QElemType&e)
{
QueuePtrp;
if(Q.front==Q.rear)
return0;
p=Q.front->next;
e=p->data;
return1;
}
voidEnQueue(LinkQueue&Q,QElemTypee)
{
QueuePtrp;
if(!
(p=(QueuePtr)malloc(sizeof(QNode))))
exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
StatusDeQueue(LinkQueue&Q,QElemType&e)
{
QueuePtrp;
if(Q.front==Q.rear)
return0;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
return1;
}
voidQueueTraverse(LinkQueueQ,void(*vi)(QElemType))
{
QueuePtrp;
p=Q.front->next;
while(p)
{
vi(p->data);
p=p->next;
}
printf("\n");
}
voidBFSTraverse(ALGraphG)
{
intv,u,w;
LinkQueueQ;
for(v=1;v<=G.vexnum;++v)
visited[v]=0;
InitQueue(Q);
for(v=1;v<=G.vexnum;v++)
if(!
visited[v])
{
visited[v]=1;
printf("%d",G.vertices[v].data);
EnQueue(Q,v);
while(!
QueueEmpty(Q))
{
DeQueue(Q,u);
for(w=FirstAdjVex(G,G.vertices[u].data);w>=1;w=NextAdjVex(G,G.vertices[u].data,G.vertices[w].data))
if(!
visited[w])
{
visited[w]=1;
printf("%d",G.vertices[w].data);
EnQueue(Q,w);
}
}
}
printf("\n");
}
voidmain()
{
ALGraphG;
CreateGraph(G);
printf("图的深度优先遍历的序列为");
DFSTraverse(G);
printf("图的广度优先遍历的序列为");
BFSTraverse(G);
}