实验五图的操作及应用.docx
- 文档编号:27562809
- 上传时间:2023-07-02
- 格式:DOCX
- 页数:14
- 大小:18.18KB
实验五图的操作及应用.docx
《实验五图的操作及应用.docx》由会员分享,可在线阅读,更多相关《实验五图的操作及应用.docx(14页珍藏版)》请在冰豆网上搜索。
实验五图的操作及应用
实验五:
图的操作及应用
实验学时:
4
实验类型:
综合型
一、实验目的
1.理解图的逻辑结构和物理结构;
2.掌握图的邻接矩阵和邻接表存储表示的实现方法;
3.掌握图的深度优先和广度优先遍历算法的实现;
4.掌握拓扑排序算法的实现方法。
二、实验条件
VisualC++6.0
三、实验原理及相关知识
1.图的邻接矩阵和邻接表存储结构的描述;
2.图的邻接矩阵和邻接表存储表示的算法;
3.图的深度优先和广度优先遍历算法;
4.拓扑排序算法。
四、实验步骤
1.实现图的邻接矩阵的存储表示。
2.实现图的邻接表存储表示。
3.实现图的深度优先和广度优先遍历算法。
4.实现拓扑排序算法。
5.调用以上函数实现以下操作:
(1)建立图。
(2)输出基于邻接表存储的深度优先和广度优先遍历序列。
(3)输出有向图的拓扑排序序列。
参考代码:
要求:
补充完整以下代码使其能够运行通过。
#include"stdio.h"
#include"malloc.h"
#include"string.h"
#defineINFINITY10000//用整型最大值代替∞
#defineMAX_VERTEX_NUM20//最大顶点个数
#defineOK1
#defineERROR0
#defineFALSE0
#defineTRUE1
#defineMAXQSIZE100
typedefintQElemType;
typedeffloatVRType;
typedeffloatInfoType;
typedefcharVertexType;
typedefcharVexType;
//============邻接矩阵的定义============
typedefstruct{
VRTypeadj;
InfoTypeinfo;//该弧相关信息的指针(可无)
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedefstruct{
VertexTypevexs[MAX_VERTEX_NUM][100];//顶点向量
AdjMatrixarcs;//邻接矩阵
intvexnum,arcnum;//图的当前顶点数和弧数
}MGraph;
//=======================邻接矩阵的定义========
//=================================邻接表的定义=========
typedefstructArcNode{//表结点
intadjvex;//该弧所指向的顶点的位置
structArcNode*nextarc;//指向下一条弧的指针
floatinfo;//网的权值指针
}ArcNode;
typedefstruct{//头结点
VertexTypedata[100];//顶点信息
ArcNode*firstarc;//第一个表结点的地址
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct{
AdjListvertices;
intvexnum,arcnum;//图的当前顶点数和弧数
}ALGraph;
intvisited[MAX_VERTEX_NUM];
//=================邻接表的定义=========================
//=========队列定义和基本操作===============
typedefstructQNode1{
QElemTypedata;
structQNode1*next;
}QNode,*QueuePtr;
typedefstruct{//链队列的定义
QElemType*base;
intfront;
intrear;
}SqQueue;
typedefstruct{
QueuePtrfront;
QueuePtrrear;
}LinkQueue;
LinkQueueInitQueue(LinkQueueQ){
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!
Q.front)
exit
(1);
Q.front->next=NULL;
returnQ;
}
intEnQueue(LinkQueue*Q,QElemTypee){
QueuePtrp;
if(!
(p=(QueuePtr)malloc(sizeof(QNode))))
returnERROR;
p->data=e;
p->next=NULL;
Q->rear->next=p;
Q->rear=p;
returnOK;
}
intDeQueue(LinkQueue*Q,QElemType*e){
QueuePtrp;
if(Q->front==Q->rear)
returnERROR;
p=Q->front->next;
*e=p->data;
Q->front->next=p->next;
if(Q->rear==p)Q->rear=Q->front;
free(p);
returnOK;
}
intQueueEmpty(LinkQueue*Q){
if(Q->front==Q->rear)return1;
elsereturn0;
}
intDestroyQueue(LinkQueue*Q){
while(Q->front){
Q->rear=Q->front->next;
free(Q->front);
Q->front=Q->rear;
}
returnOK;
}
//===================队列定义和基本操作===============
intLocateVex(MGraphG,char*vert)
{inti;
for(i=0;i if(strcmp(G.vexs[i],vert)==0) returni; return-1; } intLocateVex1(ALGraphG,char*vert) {inti; for(i=0;i if(strcmp(G.vertices[i].data,vert)==0) returni; return-1; } MGraphCreateGraph_UDN(MGraphG){//建立无向网G的邻接矩阵 inti,j,k; floatw; VexTypev1[100],v2[100]; printf("输入顶点数,数边数: "); scanf("%d%d",&G.vexnum,&G.arcnum); for(i=0;i {printf("输入第%d个顶点的信息: ",i+1); scanf("%s",&G.vexs[i]); } for(i=0;i for(j=0;j G.arcs[i][j].adj=INFINITY; for(k=0;k printf("输入第%d条边依附的两个顶点和边上的权值: ",k+1); scanf("%s%s%f",&v1,&v2,&w); //查询两个顶点在图中存储的位置 i=LocateVex(G,v1); j=LocateVex(G,v2); if(i==-1||j==-1) {printf("输入的边不正确\n");return;} G.arcs[i][j].adj=w; G.arcs[j][i].adj=G.arcs[i][j].adj; } returnG; } ALGraphCreateALGraph_UDN(ALGraphG)//建立无向网G的邻接表 { inti,j,k; floatw; ArcNode*p; VexTypev1[100],v2[100]; printf("输入顶点数,数边数: "); scanf("%d%d",&(G.vexnum),&(G.arcnum));/*读入顶点数和边数*/ for(i=0;i { printf("输入第%d个顶点的信息: ",i+1); scanf("%s",&(G.vertices[i].data));/*读入顶点信息*/ G.vertices[i].firstarc=NULL;/*顶点的边表头指针设为空*/ } for(k=0;k { printf("输入一条边依附的两个顶点和边上的权值: "); scanf("%s%s%f",&v1,&v2,&w);/*读入边 i=LocateVex1(G,v1); j=LocateVex1(G,v2); if(i==-1||j==-1) {printf("输入的边不正确\n");return;} p=(ArcNode*)malloc(sizeof(ArcNode));/*生成新边表结点p*/ p->adjvex=j;/*邻接点序号为j*/ p->info=w; p->nextarc=G.vertices[i].firstarc;/*将新边表结点p插入到顶点Vi的链表头部*/ G.vertices[i].firstarc=p; p=(ArcNode*)malloc(sizeof(ArcNode));/*生成新边表结点p*/ p->adjvex=i;/*邻接点序号为i*/ p->info=w; p->nextarc=G.vertices[j].firstarc;/*将新边表结点p插入到顶点Vj的链表头部*/ G.vertices[j].firstarc=p; } returnG; }/*CreateALGraph*/ VisitFunc(char*ch)//输出顶点的信息 { printf("%s",ch); } voidDFS(ALGraphG,intv){ intj; ArcNode*p; VisitFunc(G.vertices[v].data);//访问第v个顶点 visited[v]=TRUE;//设置访问标志为TRUE(已访问) for(p=G.vertices[v].firstarc;p;p=p->nextarc) { j=p->adjvex; if(! visited[j])DFS(G,j); } } voidDFSTraverse(ALGraphG){//图的深度优先遍历算法 intv; for(v=0;v visited[v]=FALSE;//访问标志数组初始化(未被访问) for(v=0;v if(! visited[v]) DFS(G,v);//对尚未访问的顶点调用DFS } voidBFSTraverse(ALGraphG)//图的广度优先遍历算法 { intv,j,u; ArcNode*p; LinkQueueQ; Q=InitQueue(Q);//置空的辅助队列Q for(v=0;v visited[v]=FALSE;//置初值 for(v=0;v if(! visited[v]){ visited[v]=TRUE;//设置访问标志为TRUE(已访问) VisitFunc(G.vertices[v].data); EnQueue(&Q,v);//v入队列 while(! QueueEmpty(&Q)){ DeQueue(&Q,&u);//队头元素出队并置为u for(p=G.vertices[u].firstarc;p;p=p->nextarc) { j=p->adjvex; if(! visited[j]) {visited[j]=TRUE; VisitFunc(G.vertices[j].data); EnQueue(&Q,j); } } } } DestroyQueue(&Q); } //实现建立有向网的邻接矩阵和邻接表的函数 MGraphCreateGraph_DN(MGraphG){//建立有向网G的邻接矩阵 { } ALGraphCreateALGraph_DN(ALGraphG)//建立有向网G的邻接表 { } Print_MGraph(MGraphG)//输出图的邻接矩阵表示 { inti,j; for(i=0;i {for(j=0;j printf("%f",G.arcs[i][j].adj);/*邻接矩阵*/ printf("\n"); } } Print_ALGraph(ALGraphG)//输出图的邻接表表示 { inti,j; ArcNode*p; for(i=0;i { printf("%s",G.vertices[i].data);/*顶点信息*/ p=G.vertices[i].firstarc; while(p! =NULL)/*表节点信息*/ { printf("->%s",G.vertices[p->adjvex].data); p=p->nextarc; }/*顶点的边表头指针设为空*/ printf("\n"); } } voidFindInDegree(ALGraphG,int*indegree) { inti,k;ArcNode*p; for(i=0;i { for(p=G.vertices[i].firstarc;p;p=p->nextarc){ {k=p->adjvex;indegree[k]++;} } } } //===================拓扑排序============================== intTopologicalSort(ALGraphG){ //有向图G采用邻接表存储结构。 //若G无回路,则输出G的顶点的一个拓扑序列并返回OK,否则ERROR。 intSqStack[MAX_VERTEX_NUM],top=0; intcount,k,i; ArcNode*p; intindegree[MAX_VERTEX_NUM]; for(i=0;i FindInDegree(G,indegree);//对各顶点求入度indegree[0..vernum-1] for(i=0;i if(! indegree[i]){SqStack[top]=i;top++;}//入度为0者进栈 count=0;//对输出顶点计数 while(top){ top--; i=SqStack[top]; printf("%d->",G.vertices[i].data);++count;//输出i号顶点并计数 for(p=G.vertices[i].firstarc;p;p=p->nextarc){ k=p->adjvex;//对i号顶点的每个邻接点的入度减1 if(! (--indegree[k])){SqStack[top]=k;top++;}//若入度减为0,则入栈 } } if(count ");returnERROR;}//该有向图有回路 elsereturnOK; }//TopologicalSort //======================拓扑排序===================== main() { MGraphG1,G3; ALGraphG2,G4; intP[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; floatD[MAX_VERTEX_NUM]; G1=CreateGraph_UDN(G1); G2=CreateALGraph_UDN(G2); Print_ALGraph(G2); DFSTraverse(G2); BFSTraverse(G2); //建立有向网G3的邻接矩阵 //建立有向网G4的邻接表 //输出有向网G3邻接矩阵 //输出有向网G4邻接表 //深度优先和广度优先遍历有向网G4 //TopologicalSort(G4);//求邻接表表示的有向图的拓扑排序 } 五、思考题及其它 基于邻接矩阵的图的深度和广度优先遍历算法; 最小生成树算法。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 操作 应用