数据结构图的基本操作.docx
《数据结构图的基本操作.docx》由会员分享,可在线阅读,更多相关《数据结构图的基本操作.docx(15页珍藏版)》请在冰豆网上搜索。
数据结构图的基本操作
1.实验题目
图的基本操作
2.实验目的
1)掌握图的邻接矩阵、邻接表的表示方法。
2)掌握建立图的邻接矩阵的算法。
3)掌握建立图的邻接表的算法。
4)加深对图的理解,逐步培养解决实际问题的编程能力
3.需求分析
(1)编写图基本操作函数。
①建立图的邻接表,邻接矩阵Create_Graph(LGraphlg.MGraphmg)
②邻接表表示的图的递归深度优先遍历LDFS(LGraphg,inti)
③邻接矩阵表示的图的递归深度优先遍历MDFS(MGraphg,inti,intvn)
④邻接表表示的图的广度优先遍历LBFS(LGraphg,ints,intn)
⑤邻接矩阵表示的图的广度优先遍历MBFS(MGraphg,ints,intn)
(2)调用上述函数实现下列操作。
①建立一个图的邻接矩阵和图的邻接表。
②采用递归深度优先遍历输出图的邻接矩阵
③采用递归深度优先遍历输出图的邻接表。
④采用图的广度优先调历输出图的邻接表。
⑤采用图的广度优先遍历输出图的邻接矩阵
4.概要设计
(1):
/**********************************图的基本操作**********************************/
//-------------------------------邻接矩阵数据类型的定义--------------------------------
//最大顶点个数
typedefstruct
{
charvexs[MAX_VERTEX_NUM];//顶点向量
intacrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵
intvexnum,arcnum;//图当前顶点数和弧数
}MGraph;
//--------------------------------邻接表数据类型的定义----------------------------------
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
}ArcNode;
typedefstructVNode
{
chardata;//顶点信息
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;//图当前顶点数和弧数
}LGraph;
(2)本程序主要包含6个函数:
•主函数main()
•建立图的邻接矩阵,邻接表Create_Graph()
•邻接表表示的图的递归深度优先遍历LDFS()
•邻接矩阵表示的图的递归深度优先遍历MDFS()
•邻接表表示的图的广度优先遍历LBFS()
•邻接矩阵表示的图的广度优先遍历MBFS()
各函数间调用关系如下:
(3)主函数的伪码
main()
{定义邻接矩阵和邻接表;
建立邻接矩阵和邻接表;
邻接矩阵MDFS深度优先遍历;
邻接矩阵MBFS广度优先遍历;
邻接表LDFS深度优先遍历;
邻接表LBFS广度优先遍历
}
5详细设计
/**********************************图的基本操作**********************************/
//-------------------------------邻接矩阵数据类型的定义--------------------------------
//最大顶点个数
typedefstruct
{
charvexs[MAX_VERTEX_NUM];//顶点向量
intacrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵
intvexnum,arcnum;//图当前顶点数和弧数
}MGraph;
//--------------------------------邻接表数据类型的定义----------------------------------
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
}ArcNode;
typedefstructVNode
{
chardata;//顶点信息
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;//图当前顶点数和弧数
}LGraph;
intCreate_Graph(MGraph*Mg,LGraph*Lg)//建立图的邻接矩阵,邻接表
{
输入图的顶点个数(字符),构造顶点向量
输入图的任意两个顶点的弧
构造邻接矩阵
构造邻接表
}
voidLDFS(LGraph*Lg,inti)邻接表表示的图的递归深度优先遍历
{
显示顶点向量,
指针指向下一个顶点向量
下一个顶点没有被访问,继续
否则退会上一个顶点向量的另一个边
}
voidMDFS(MGraph*Mg,inti)邻接矩阵表示的图的递归深度优先遍历
{
显示顶点向量,
指针指向下一个顶点向量
下一个顶点没有被访问,继续
否则退会上一个顶点向量的另一个边
}
voidLBFS(LGraph*Lg)邻接表表示的图的广度优先遍历
{
初始化visited[]
初始化队列
没被访问过
显示顶点向量入队
出队访问下一个顶点向量
}
voidMBFS(MGraph*Mg)邻接矩阵表示的图的广度优先遍历
{
初始化visited[]
初始化队列
没被访问过
显示顶点向量入队
出队访问下一个顶点向量
}
//-------------------主函数-------------------------------
main()
{定义邻接矩阵和邻接表;
建立邻接矩阵和邻接表;
邻接矩阵MDFS深度优先遍历;
邻接矩阵MBFS广度优先遍历;
邻接表LDFS深度优先遍历;
邻接表LBFS广度优先遍历
}
6测试结果
7.参考文献
《数据结构》
8.附录
#include
#include
#include
#include
#defineOK1
#defineERROR0
#defineMAX_VERTEX_NUM20
/**********************************图的基本操作**********************************/
intvisited[MAX_VERTEX_NUM];//访问标志数组
//-------------------------------邻接矩阵数据类型的定义--------------------------------
//最大顶点个数
typedefstruct
{
charvexs[MAX_VERTEX_NUM];//顶点向量
intacrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵
intvexnum,arcnum;//图当前顶点数和弧数
}MGraph;
//--------------------------------邻接表数据类型的定义----------------------------------
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
}ArcNode;
typedefstructVNode
{
chardata;//顶点信息
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;//图当前顶点数和弧数
}LGraph;
//_________________________________队列函数__________________________________________
typedefstructQueue
{
intarry[MAX_VERTEX_NUM];
intfront,rear;
}Queue;
QueueQ;
voidInitQueue()//队列初始化
{
Q.front=Q.rear=0;
}
intQueueEmpty(Queue*Q)//清空队列
{
if(Q->front==Q->rear)
return1;
else
return0;
}
voidEnQueue(Queue*Q,intw)//入队
{
if((Q->rear+1)%MAX_VERTEX_NUM==Q->front)
printf("Error!
");
else
{
Q->arry[Q->rear]=w;
Q->rear=(Q->rear+1)%MAX_VERTEX_NUM;
}
}
intDeQueue(Queue*Q)//出队
{
intu;
if(Q->front==Q->rear)
return-1;
u=Q->front;
Q->front=(Q->front+1)%MAX_VERTEX_NUM;
returnu;
}
//____________________________________队列函数end_______________________________________
/****************************************************************************************
*函数:
Create_Graph
*功能:
建立图的邻接矩阵,邻接表
*说明:
该构建的为无向网mg为邻接矩阵,lg为邻接表,无权值
***************************************************************************************/
intLocatevex(MGraph*Mg,charv)//确定v元素在Mg中的位置
{
inti;
for(i=0;Mg->vexs[i]!
=v;i++);
if(i>Mg->vexnum)//输入的元素不正确则显示错误
printf("ERROR");
returni;//返回位置
}
intCreate_Graph(MGraph*Mg,LGraph*Lg)//建立图的邻接矩阵,邻接表
{
inti,j,k;
charv1,v2;
ArcNode*q,*p;
printf("输入图的顶点数和弧数:
");
scanf("%d%d",&Mg->vexnum,&Mg->arcnum);
getchar();
Lg->vexnum=Mg->vexnum;//邻接表的顶点数和弧数
Lg->arcnum=Mg->arcnum;
for(i=0;ivexnum;i++)//构造顶点向量
{
printf("请输入一个图的顶点(字符):
");
scanf("%c",&Mg->vexs[i]);
getchar();
Lg->vertices[i].data=Mg->vexs[i];//赋值
Lg->vertices[i].firstarc=NULL;//指向第一条依附该顶点的弧的指针为空
}
for(i=0;ivexnum;i++)//初始化邻接矩阵
for(j=0;jvexnum;j++)
Mg->acrs[i][j]=0;
for(k=0;karcnum;k++)//构造邻接矩阵和邻接表
{
printf("请输入一条边连接的2个顶点:
");
scanf("%c%c",&v1,&v2);
getchar();
i=Locatevex(Mg,v1);//确定v1在Mg中的位置
j=Locatevex(Mg,v2);//确定v2在Mg中的位置
Mg->acrs[j][i]=Mg->acrs[i][j]=1;//置《v1,v2》的对称弧《v2,v1》
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=i;//确认顶点位置
p->nextarc=Lg->vertices[j].firstarc;//指向下一条弧的指针
Lg->vertices[j].firstarc=p;//赋值
q=(ArcNode*)malloc(sizeof(ArcNode));
q->adjvex=j;//确认顶点位置
q->nextarc=Lg->vertices[i].firstarc;//指向下一条弧的指针
Lg->vertices[i].firstarc=q;//赋值
}
returnOK;
}
/****************************************************************************************
*函数:
LDFS
*功能:
邻接表表示的图的递归深度优先遍历
*说明:
***************************************************************************************/
intLAdjVex(LGraph*Lg,intk)//位置
{
ArcNode*p;
for(p=Lg->vertices[k].firstarc;p!
=NULL;p=p->nextarc)
if(!
visited[p->adjvex])
returnp->adjvex;
return-1;
}
voidLDFS(LGraph*Lg,inti)
{
intk;
visited[i]=OK;
printf("%c",Lg->vertices[i].data);
for(k=LAdjVex(Lg,i);k>=0;k=LAdjVex(Lg,k))
if(!
visited[k])
LDFS(Lg,k);
}
/****************************************************************************************
*函数:
MDFS
*功能:
邻接矩阵表示的图的递归深度优先遍历
*说明:
***************************************************************************************/
intAdjVes(MGraph*Mg,intk)//位置
{
inti;
for(i=0;ivexnum;i++)
if(Mg->acrs[k][i]&&(!
visited[i]))
returni;
return-1;
}
voidMDFS(MGraph*Mg,inti)//递归深度优先遍历
{
intk;
visited[i]=1;//访问标志数组某位置1
printf("%c",Mg->vexs[i]);//显示
for(k=AdjVes(Mg,i);k>=0;k=AdjVes(Mg,k))
if(!
visited[k])
MDFS(Mg,k);//递归
}
/****************************************************************************************
*函数:
LBFS
*功能:
邻接表表示的图的广度优先遍历
*说明:
***************************************************************************************/
voidLBFS(LGraph*Lg)
{
inti,u,w;
for(i=0;ivexnum;++i)//初始化visited[]
visited[i]=0;
InitQueue();//初始化队列
for(i=0;ivexnum;++i)
if(!
visited[i])//没被访问过
{
visited[i]=1;
printf("%c",Lg->vertices[i].data);
EnQueue(&Q,i);//入队
while(!
QueueEmpty(&Q))
{
u=DeQueue(&Q);//出队
for(w=LAdjVex(Lg,u);w>=0;w=LAdjVex(Lg,u))
if(!
visited[w])//没被访问过
{
visited[w]=1;
printf("%c",Lg->vertices[w].data);
EnQueue(&Q,w);//入队
}
}
}
}
/****************************************************************************************
*函数:
MBFS
*功能:
邻接矩阵表示的图的广度优先遍历
*说明:
***************************************************************************************/
voidMBFS(MGraph*Mg)
{
inti,w,u;
for(i=0;ivexnum;i++)//初始化visited[]
visited[i]=0;
InitQueue();//初始化队列
for(i=0;ivexnum;++i)
if(!
visited[i])//没被访问过
{
visited[i]=1;
printf("%c",Mg->vexs[i]);//显示
EnQueue(&Q,i);//入队
while(!
QueueEmpty(&Q))
{
u=DeQueue(&Q);//出队
for(w=AdjVes(Mg,u);w>=0;w=AdjVes(Mg,u))
if(!
visited[w])//没被访问过
{
visited[w]=1;
printf("%c",Mg->vexs[w]);
//显示
EnQueue(&Q,w);//入队
}
}
}
}
/***************************************主函数*******************************************/
voidmain()
{
inti;
MGraphMg;
LGraphLg;
Create_Graph(&Mg,&Lg);
printf("邻接矩阵MDFS深度优先遍历:
\t");
for(i=0;ivisited[i]=0;//初始化visited[]
for(i=0;iif(!
visited[i])
MDFS(&Mg,i);//遍历Mg
printf("\n邻接矩阵MBFS广度优先遍历:
\t");
MBFS(&Mg);//遍历Mg
printf("\n");
printf("邻接表LDFS深度优先遍历:
\t");
for(i=0;ivisited[i]=0;//初始化visited[]
for(i=0;iif(!
visited[i])
LDFS(&Lg,i);//遍历Lg
printf("\n邻接表LBFS广度优先遍历:
\t");
LBFS(&Lg);//遍历Lg
printf("\n");
}}注意事项:
●每位同学必须完成实验任务,并提交实验报告。
杜绝抄袭和拷贝,一经发现该次实验雷同报告均以零分计。
●请将实验报告以电子文档提交,“网络工程”,“电子信息”信箱中,请附上程序清单.C源程序文件、和实验报告WORD文档