实验五图的操作及应用.docx

上传人:b****3 文档编号:27562809 上传时间:2023-07-02 格式:DOCX 页数:14 大小:18.18KB
下载 相关 举报
实验五图的操作及应用.docx_第1页
第1页 / 共14页
实验五图的操作及应用.docx_第2页
第2页 / 共14页
实验五图的操作及应用.docx_第3页
第3页 / 共14页
实验五图的操作及应用.docx_第4页
第4页 / 共14页
实验五图的操作及应用.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

实验五图的操作及应用.docx

《实验五图的操作及应用.docx》由会员分享,可在线阅读,更多相关《实验五图的操作及应用.docx(14页珍藏版)》请在冰豆网上搜索。

实验五图的操作及应用.docx

实验五图的操作及应用

实验五:

图的操作及应用

实验学时:

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);//求邻接表表示的有向图的拓扑排序

}

五、思考题及其它

基于邻接矩阵的图的深度和广度优先遍历算法;

最小生成树算法。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1