邻接矩阵表示的图的基本操作的实现.docx

上传人:b****6 文档编号:8755212 上传时间:2023-05-14 格式:DOCX 页数:11 大小:16.53KB
下载 相关 举报
邻接矩阵表示的图的基本操作的实现.docx_第1页
第1页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第2页
第2页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第3页
第3页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第4页
第4页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第5页
第5页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第6页
第6页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第7页
第7页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第8页
第8页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第9页
第9页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第10页
第10页 / 共11页
邻接矩阵表示的图的基本操作的实现.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

邻接矩阵表示的图的基本操作的实现.docx

《邻接矩阵表示的图的基本操作的实现.docx》由会员分享,可在线阅读,更多相关《邻接矩阵表示的图的基本操作的实现.docx(11页珍藏版)》请在冰点文库上搜索。

邻接矩阵表示的图的基本操作的实现.docx

邻接矩阵表示的图的基本操作的实现

邻接矩阵表示的图的基本操作的实现

//采用邻接矩阵完成无权无向及有向图的"建立、输出、深度遍历、广度遍历"操作

#include

#include

#defineOK1

#defineERROR-1

typedefintStatus;

typedefintElemType;//此例中设元素为单值元素,类型为整型

#defineMAX_VERTEX_NUM20//最大顶点个数

typedefintElemType;//图顶点数据类型

typedefintQueueElemType;//队列结点数据类型

//链表结点类型定义

typedefstructQnode

{

QueueElemTypedata;

structQnode*next;

}QNode;

//队列类型定义:

typedefstructLinkqueue

{

QNode*front,*rear;

}LinkQueue;

//图的数据类型定义

typedefstructMgraph

{

ElemTypevector[MAX_VERTEX_NUM];//顶点向量

intadj[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵

intvexnum;//图中当前顶点数

intarcnum;//图中当前边数

}MGraph;

//队列初始化

StatusInitLinkQueue(LinkQueue*Q)

{

QNode*p;

p=(QNode*)malloc(sizeof(QNode));//开辟头结点空间

if(p!

=NULL)

{

p->next=NULL;

Q->front=Q->rear=p;

returnOK;

}

else

returnERROR;

}

//链式队列的入队操作,在已知队列的队尾插入一个元素e,修改队尾指针rear。

StatusInsertLinkQueue(LinkQueue*Q,ElemTypee)

{

QNode*p;

p=(QNode*)malloc(sizeof(QNode));

if(p==NULL)

returnERROR;//申请新结点空间失败,返回错误标志

else

{

p->data=e;//存入新结点数据

p->next=NULL;

Q->rear->next=p;//新结点插入到队尾

Q->rear=p;//新插入结点成为新的队尾

returnOK;

}

}

//链式队列的出队操作,取第一个数据结点的数据后删除该结点

StatusDeleteLinkQueue(LinkQueue*Q,ElemType*e)

{

QNode*p;

if(Q->front==Q->rear)//可改为:

if(Q->front->next==NULL)

returnERROR;//队空

else

{

p=Q->front->next;//取队首结点

*e=p->data;

Q->front->next=p->next;//修改队首指针

if(p==Q->rear)//条件成立说明只有一个数据结点

Q->rear=Q->front;//当队列只有一个数据结点时应防止丢失队尾指针

free(p);

Q->rear->next=NULL;

returnOK;

}

}

//判断队列是否为空

StatusIsEmptyLinkQueue(LinkQueue*Q)

{

if(Q->front==Q->rear)

returnOK;

else

returnERROR;

}

//释放队列

voidDestroyLinkQueue(LinkQueue*Q)

{

QNode*p,*q;

p=Q->front;//指向链表第一个结点,即整个链表的第一个结点

while(p!

=NULL)

{

q=p->next;//保存链表后半段首地址以防丢失

free(p);

p=q;

}

}

/**************以下为图的操作************/

//顶点在顶点向量中的定位,找到返回OK,否则返回ERROR

//G为的数据结构,v为待查顶点,n用于返回找到的顶点下标

StatusLocateVex(MGraphG,ElemTypev,int*n)

{

inti;

for(i=0;((i

=v));i++)

;

*n=i;

if(i

returnOK;

else

returnERROR;

}

//建立无向图的邻接矩阵

voidCreateGraph(MGraph*G)

{

inti,j,k,sfyxt;//sfyxt:

0-无向图其它-有向图

ElemTypev1,v2;

printf("请输入图的顶点数及边数:

");

scanf("%d%d",&(G->vexnum),&(G->arcnum));

fflush(stdin);

printf("请输入%d个顶点信息:

\n",G->vexnum);

for(i=0;ivexnum;i++)//输入顶点向量

scanf("%d",&(G->vector[i]));

printf("顶点向量如下:

\n");//输出顶点向量

for(i=0;ivexnum;i++)

printf("%4d",G->vector[i]);

printf("\n无向图还是有向图,0-无向图其它-有向图:

");

scanf("%d",&sfyxt);

for(i=0;ivexnum;i++)//邻接矩阵初始化

for(j=0;jvexnum;j++)

G->adj[i][j]=0;

printf("\n请输入无权图的边(共%d条)\n",G->arcnum);

printf("格式为:

vivj,vi及vj表示结点内容,注意有向图结点输入的前后次序:

\n");

for(k=0;karcnum;k++)//输入无权图的边

{

fflush(stdin);

printf("No.%2d/%d:

",k+1,G->arcnum);

scanf("%d%d",&v1,&v2);

LocateVex(*G,v1,&i);

LocateVex(*G,v2,&j);

G->adj[i][j]=1;

if(sfyxt==0)//无向图则同时产生两条边的信息

G->adj[j][i]=G->adj[i][j];

}

}

//输出无向图的邻接矩阵

voidPrintGraph(MGraphG)

{

inti,j;

printf("图信息如下:

\n");

printf("%4s","");

for(i=0;i

printf("%4d",G.vector[i]);

printf("\n");

for(i=0;i

{

printf("%4d",G.vector[i]);

for(j=0;j

printf("%4d",G.adj[i][j]);

printf("\n");

}

}

//查找顶点v的第一个邻接点,v为当前顶点下标

intFirstAdjVex(MGraphG,intv)

{

intj,p=-1,found=1;

for(j=0;((j

if(G.adj[v][j]==1)

{

p=j;

found=0;

}

returnp;

}

//查找顶点v的下一个邻接点,w为当前邻接点下标

intNextAdjVex(MGraphG,intv,intw)

{

intj,p=-1,found=1;

for(j=w+1;((j

if(G.adj[v][j]==1)

{

p=j;

found=0;

}

returnp;

}

//深度优先遍历

charvisited[MAX_VERTEX_NUM];//访问标志数组

voidDfs(MGraphG,intv)

{

intw;

visited[v]=1;//置当前结点为已访问状态

printf("%4d",G.vector[v]);//访问当前结点

//依次深度遍历当前结点未被遍历的邻接结点,采用递归方式实现

for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))

if(visited[w]==0)

Dfs(G,w);

}

voidDfsTraverse(MGraphG)

{

intv;

for(v=0;v

visited[v]=0;

for(v=0;v

if(visited[v]==0)

Dfs(G,v);

}

//广度优先遍历

voidBfsTraverse(MGraphG)

{

intv,u,w;

LinkQueueQ;

for(v=0;v

visited[v]=0;

InitLinkQueue(&Q);

for(v=0;v

if(visited[v]==0)

{

visited[v]=1;

printf("%4d",G.vector[v]);

InsertLinkQueue(&Q,v);

while(IsEmptyLinkQueue(&Q)!

=OK)

{

DeleteLinkQueue(&Q,&u);

for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))

if(visited[w]==0)

{

visited[w]=1;

printf("%4d",G.vector[w]);

InsertLinkQueue(&Q,w);

}

}

}

DestroyLinkQueue(&Q);

}

//主函数

voidmain()

{

intxz=1;

MGraphG;

while(xz!

=0)

{

printf("1-输入图信息\n");

printf("2-输出图信息\n");

printf("3-图的深度优先遍历\n");

printf("4-图的广度优先遍历\n");

printf("0-退出\n请选择:

");

fflush(stdin);

scanf("%d",&xz);

switch(xz)

{

case1:

CreateGraph(&G);

break;

case2:

PrintGraph(G);

break;

case3:

DfsTraverse(G);

printf("\n");

break;

case4:

BfsTraverse(G);

printf("\n");

break;

case0:

printf("再见!

\n");

break;

default:

printf("输入错误!

\n");

break;

}

}

}

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

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2