当前位置:文档之家› 数据结构——图的基本操作

数据结构——图的基本操作

- .1.实验题目图的基本操作2.实验目的1)掌握图的邻接矩阵、邻接表的表示方法。

2)掌握建立图的邻接矩阵的算法。

3)掌握建立图的邻接表的算法。

4)加深对图的理解,逐步培养解决实际问题的编程能力3.需求分析(1)编写图基本操作函数。

①建立图的邻接表,邻接矩阵Create_Graph( LGraph lg. MGraph mg )②邻接表表示的图的递归深度优先遍历LDFS( LGraph g, int i )③邻接矩阵表示的图的递归深度优先遍历MDFS( MGraph g,int i, int vn )④邻接表表示的图的广度优先遍历LBFS( LGraph g, int s, int n )⑤邻接矩阵表示的图的广度优先遍历MBFS(MGraph g, int s, int n )(2)调用上述函数实现下列操作。

①建立一个图的邻接矩阵和图的邻接表。

②采用递归深度优先遍历输出图的邻接矩阵③采用递归深度优先遍历输出图的邻接表。

④采用图的广度优先调历输出图的邻接表。

⑤采用图的广度优先遍历输出图的邻接矩阵4.概要设计(1):/**********************************图的基本操作**********************************///------------------------------- 邻接矩阵数据类型的定义--------------------------------// 最大顶点个数typedef struct{char vexs[MAX_VERTEX_NUM]; // 顶点向量int acrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵int vexnum,arum; // 图当前顶点数和弧数}MGraph ;//--------------------------------邻接表数据类型的定义---------------------------------- typedef struct Arode{int adjvex;// 该弧所指向的顶点的位置struct Arode *nextarc;// 指向下一条弧的指针}Arode;typedef struct VNode { char data;// 顶点信息Arode *firstarc;// 指向第一条依附该顶点的弧的指针}VNode, AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices;int vexnum,arum;// 图当前顶点数和弧数}LGraph;(2) 本程序主要包含6个函数:• 主函数main()• 建立图的邻接矩阵,邻接表Create_Graph() • 邻接表表示的图的递归深度优先遍历LDFS() • 邻接矩阵表示的图的递归深度优先遍历 MDFS()• 邻接表表示的图的广度优先遍历LBFS() • 邻接矩阵表示的图的广度优先遍历MBFS () 各函数间调用关系如下:(3) 主函数的伪码main(){ 定义邻接矩阵和邻接表;建立邻接矩阵和邻接表; 邻接矩阵MDFS 深度优先遍历;mainCreate_Graph () LDFS () MDFS () LBFS () MBFS ()邻接矩阵MBFS广度优先遍历;邻接表LDFS深度优先遍历;邻接表LBFS广度优先遍历}5详细设计/**********************************图的基本操作**********************************///------------------------------- 邻接矩阵数据类型的定义--------------------------------// 最大顶点个数typedef struct{char vexs[MAX_VERTEX_NUM]; // 顶点向量int acrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵int vexnum,arum; // 图当前顶点数和弧数}MGraph ;//--------------------------------邻接表数据类型的定义---------------------------------- typedef struct Arode{int adjvex; // 该弧所指向的顶点的位置struct Arode *nextarc; // 指向下一条弧的指针}Arode;typedef struct VNode{char data; // 顶点信息Arode *firstarc; // 指向第一条依附该顶点的弧的指针}VNode, AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arum; // 图当前顶点数和弧数}LGraph;int Create_Graph( MGraph *Mg , LGraph *Lg ) // 建立图的邻接矩阵,邻接表{输入图的顶点个数(字符),构造顶点向量输入图的任意两个顶点的弧构造邻接矩阵构造邻接表}void LDFS(LGraph *Lg,int i) 邻接表表示的图的递归深度优先遍历{显示顶点向量,指针指向下一个顶点向量下一个顶点没有被访问,继续否则退会上一个顶点向量的另一个边}void MDFS(MGraph *Mg,int i)邻接矩阵表示的图的递归深度优先遍历{显示顶点向量,指针指向下一个顶点向量下一个顶点没有被访问,继续否则退会上一个顶点向量的另一个边}void LBFS( LGraph *Lg )邻接表表示的图的广度优先遍历{初始化visited[]初始化队列没被访问过显示顶点向量入队出队访问下一个顶点向量}void MBFS(MGraph *Mg )邻接矩阵表示的图的广度优先遍历{初始化visited[]初始化队列没被访问过显示顶点向量入队出队访问下一个顶点向量}//-------------------主函数------------------------------- main(){ 定义邻接矩阵和邻接表;建立邻接矩阵和邻接表;邻接矩阵MDFS深度优先遍历;邻接矩阵MBFS广度优先遍历;邻接表LDFS深度优先遍历;邻接表LBFS广度优先遍历}6测试结果7. 参考文献《数据结构》8.附录#include <stdio.h>#include <malloc.h>#include <stddef.h>#include <math.h>#define OK 1#define ERROR 0#define MAX_VERTEX_NUM 20/**********************************图的基本操作**********************************/int visited[MAX_VERTEX_NUM]; // 访问标志数组//------------------------------- 邻接矩阵数据类型的定义-------------------------------- // 最大顶点个数typedef struct{char vexs[MAX_VERTEX_NUM]; // 顶点向量int acrs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵int vexnum,arum; // 图当前顶点数和弧数}MGraph ;//--------------------------------邻接表数据类型的定义----------------------------------typedef struct Arode{int adjvex; // 该弧所指向的顶点的位置struct Arode *nextarc; // 指向下一条弧的指针}Arode;typedef struct VNode{char data; // 顶点信息Arode *firstarc; // 指向第一条依附该顶点的弧的指针}VNode, AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arum; // 图当前顶点数和弧数}LGraph;//_________________________________队列函数__________________________________________ typedef struct Queue{int arry[MAX_VERTEX_NUM];int front,rear;}Queue;Queue Q;void InitQueue() // 队列初始化{Q.front=Q.rear=0;}int QueueEmpty(Queue *Q) // 清空队列{if(Q->front==Q->rear)return 1;elsereturn 0;}void EnQueue(Queue *Q,int w)// 入队{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;}}int DeQueue(Queue *Q) // 出队{int u;if(Q->front==Q->rear)return -1;u=Q->front;Q->front=(Q->front+1)%MAX_VERTEX_NUM;return u;}//____________________________________队列函数end_______________________________________ /**************************************************************************************** *函数:Create_Graph*功能:建立图的邻接矩阵,邻接表*说明:该构建的为无向网mg 为邻接矩阵,lg为邻接表, 无权值***************************************************************************************/ int Locatevex(MGraph *Mg , char v) // 确定v 元素在Mg中的位置{int i;for(i=0;Mg->vexs[i]!=v;i++);if(i>Mg->vexnum) // 输入的元素不正确则显示错误printf("ERROR ");return i; // 返回位置}int Create_Graph( MGraph *Mg , LGraph *Lg ) // 建立图的邻接矩阵,邻接表{int i , j , k ;char v1 , v2 ;Arode *q,*p;printf("输入图的顶点数和弧数: ");scanf("%d %d",&Mg->vexnum,&Mg->arum);getchar();Lg->vexnum=Mg->vexnum; // 邻接表的顶点数和弧数Lg->arum=Mg->arum;for(i=0;i<Mg->vexnum;i++) // 构造顶点向量{printf("请输入一个图的顶点(字符):");scanf("%c" , &Mg->vexs[i]);getchar();Lg->vertices[i].data=Mg->vexs[i]; // 赋值Lg->vertices[i].firstarc=NULL; // 指向第一条依附该顶点的弧的指针为空}for(i=0;i<Mg->vexnum;i++) // 初始化邻接矩阵for(j=0;j<Mg->vexnum;j++)Mg->acrs[i][j]=0 ;for(k=0;k<Mg->arum;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=(Arode *)malloc(sizeof(Arode));p->adjvex=i; // 确认顶点位置p->nextarc=Lg->vertices[j].firstarc;// 指向下一条弧的指针Lg->vertices[j].firstarc=p; // 赋值q=(Arode *)malloc(sizeof(Arode));q->adjvex=j; // 确认顶点位置q->nextarc=Lg->vertices[i].firstarc;// 指向下一条弧的指针Lg->vertices[i].firstarc=q; // 赋值}return OK ;}/**************************************************************************************** *函数:LDFS*功能:邻接表表示的图的递归深度优先遍历*说明:***************************************************************************************/ int LAdjVex(LGraph *Lg,int k) // 位置{Arode *p;for(p=Lg->vertices[k].firstarc;p!=NULL;p=p->nextarc)if(!visited[p->adjvex])return p->adjvex;return -1;}void LDFS(LGraph *Lg,int i){int k;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*功能:邻接矩阵表示的图的递归深度优先遍历*说明:***************************************************************************************/ int AdjVes(MGraph *Mg,int k) // 位置{int i;for(i=0;i<Mg->vexnum;i++)if(Mg->acrs[k][i]&&(!visited[i]))return i;return -1;}void MDFS(MGraph *Mg,int i) // 递归深度优先遍历{int k;visited[i]=1; // 访问标志数组某位置1printf("%c",Mg->vexs[i]); // 显示for(k=AdjVes(Mg,i);k>=0;k=AdjVes(Mg,k))if(!visited[k])MDFS(Mg,k); // 递归}/**************************************************************************************** *函数:LBFS*功能:邻接表表示的图的广度优先遍历*说明:***************************************************************************************/void LBFS( LGraph *Lg ){int i,u,w;for(i=0;i<Lg->vexnum;++i) // 初始化visited[]visited[i]=0;InitQueue(); // 初始化队列for(i=0;i<Lg->vexnum;++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*功能:邻接矩阵表示的图的广度优先遍历*说明:***************************************************************************************/ void MBFS(MGraph *Mg ){int i,w,u;for(i=0;i<Mg->vexnum;i++) // 初始化visited[]visited[i]=0;InitQueue(); // 初始化队列for(i=0;i<Mg->vexnum;++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); // 入队}}}}/***************************************主函数*******************************************/void main(){int i ;MGraph Mg;LGraph Lg;Create_Graph( &Mg, &Lg);printf("邻接矩阵MDFS深度优先遍历:\t");for(i=0;i<Mg.vexnum;i++)visited[i]=0; // 初始化visited[]for(i=0;i<Mg.vexnum;i++)if(!visited[i])MDFS(&Mg,i); // 遍历Mgprintf("\n邻接矩阵MBFS广度优先遍历:\t");MBFS(&Mg) ; // 遍历Mgprintf("\n");printf("邻接表LDFS深度优先遍历:\t");for(i=0;i<Lg.vexnum;++i)visited[i]=0; // 初始化visited[]for(i=0;i<Lg.vexnum;++i)if(!visited[i])LDFS(&Lg,i); // 遍历Lgprintf("\n邻接表LBFS广度优先遍历:\t");LBFS(&Lg) ; // 遍历Lgprintf("\n");}}注意事项:●每位同学必须完成实验任务,并提交实验报告。

相关主题