数据结构的C实现_图_邻接矩阵表示

原创 2012年03月22日 18:49:05
//编译环境 Visual Studio 2008 win32 console application
//MGragh.c
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#define MaxVertexNum 100//最大顶点数
#define QM 100 //队列的最大元素个数
#define OK 1
#define ERROR 0
int visited[MaxVertexNum];

typedef enum{DG,DN,NDG,NDN}GraphKind;//图的种类,有向图,有向网,无向图,无向网

typedef int VertexType;//顶点类型

typedef struct
{
int adj;//相邻与否,或权值大小
}ArcCell;

typedef struct
{
VertexType vexs[MaxVertexNum];//顶点表
ArcCell arcs[MaxVertexNum][MaxVertexNum];//邻接矩阵,边表
int vexnum,arcnum;//图中当前的顶点数和边数
int Graphkind;//图的种类标志
}MGragh;
////////////////////////////////////////////定义队列,用于广度优先遍历//////////////////////////////////////
typedef struct
{
VertexType *base;
VertexType front,rear;
}SQueue;

/////////////////////////////////////////函数声明///////////////////////////////////////////////////////////
int LocateVex(MGragh *M,VertexType v);
int CreateDN(MGragh *M);//有向网,带权值
int CreateDG(MGragh *M);//有向图,无权值
int CreateUDN(MGragh *M);//无向网,带权值
int CreateUDG(MGragh *M);//无向图,带权值
int CreatGragh(MGragh *G);
int FirstAdjVex(MGragh *G,int v);//返回V的第一个邻接顶点
int NextAdjVex(MGragh *G,int v,int w);//返回V的相对于W的下一个邻接顶点
void BFSTraverse(MGragh *G);//广度遍历
void DFS(MGragh *G,int v0);
void DFSTaverse(MGragh *G);//深度遍历
void PrintMatrix(MGragh *G);
void InsertVex(MGragh *G,int v);
int DeVex(MGragh *G,VertexType v);
int InserArc(MGragh *G);
int DeArc(MGragh *G);

///////////////////与队列有关的声明/////////////////////////////////
void InitQueue(SQueue *Q);
void EnQueue(SQueue *Q,int e);
int  QueueEmpty(SQueue *Q);
void DeQueue(SQueue *Q,int*e);


///////////////////////////////////////主函数/////////////////////////////////////////////////////////
void main()
{
MGragh M;
M.vexnum=M.arcnum=0;
CreatGragh(&M);
InsertVex(&M,6);
DeVex(&M,3);
InserArc(&M);
DeArc(&M);
BFSTraverse(&M);
DFSTaverse(&M);
PrintMatrix(&M);

}
//////////////////////////////////与图有关的操作////////////////////////////////////////////////////////////////
//求顶点位置
int LocateVex(MGragh *M,VertexType v)
{
int k;
for(k=0;k<M->vexnum;k++)
{
if(M->vexs[k]==v)
return k;
}
return -1;//没有这个顶点
}
//创建有向网
int CreateDN(MGragh *M)
{
int i,j,k;
int weight;
VertexType v1,v2;
printf("输入有向网的顶点数和弧数:\n");
scanf_s("%d%d",&M->vexnum,&M->arcnum);
//初始化邻接矩阵
for(i=0;i<M->vexnum;i++)
for(j=0;j<M->vexnum;j++)
M->arcs[i][j].adj=0;//初始所有点不相邻
printf("输入图的%d个顶点:\n",M->vexnum);
for(i=0;i<M->vexnum;i++)
scanf_s("%d",&M->vexs[i]);
printf("建立弧,请输入%d条弧的顶点和权值:\n",M->arcnum);
for(k=0;k<M->arcnum;k++)
{
scanf_s("%d%d%d",&v1,&v2,&weight);
i=LocateVex(M,v1);
j=LocateVex(M,v2);
if(i<0||j<0)
return ERROR;
M->arcs[i][j].adj=weight;
}
return OK;
}
//创建无向网
int CreateUDN(MGragh *M)
{
int i,j,k;
int weight;
VertexType v1,v2;
printf("输入无向网的顶点数和弧数:\n");
scanf_s("%d%d",&M->vexnum,&M->arcnum);
//初始化邻接矩阵
for(i=0;i<M->vexnum;i++)
for(j=0;j<M->vexnum;j++)
M->arcs[i][j].adj=0;//初始所有点不相邻
printf("输入图的%d个顶点:\n",M->vexnum);
for(i=0;i<M->vexnum;i++)
scanf_s("%d",&M->vexs[i]);
printf("建立弧,请输入%d条弧的顶点和权值:\n",M->arcnum);
for(k=0;k<M->arcnum;++k)
{
scanf_s("%d%d%d",&v1,&v2,&weight);
i=LocateVex(M,v1);
j=LocateVex(M,v2);
if(i<0||j<0)
return ERROR;
M->arcs[i][j].adj=weight;
M->arcs[j][i].adj=M->arcs[i][j].adj;//无向的
}
return OK;
}

//创建有向图
int CreateDG(MGragh *M)
{
int i,j,k;
int weight=1;
VertexType v1,v2;
printf("输入有向网的顶点数和弧数:\n");
scanf_s("%d%d",&M->vexnum,&M->arcnum);
//初始化邻接矩阵
for(i=0;i<M->vexnum;i++)
for(j=0;j<M->vexnum;j++)
M->arcs[i][j].adj=0;//初始所有点不相邻
printf("输入图的%d个顶点:\n",M->vexnum);
for(i=0;i<M->vexnum;i++)
scanf_s("%d",&M->vexs[i]);
printf("建立弧,请输入%d条弧的顶点:\n",M->arcnum);
for(k=0;k<M->arcnum;k++)
{
scanf_s("%d%d",&v1,&v2);
i=LocateVex(M,v1);
j=LocateVex(M,v2);
if(i<0||j<0)
return ERROR;
M->arcs[i][j].adj=weight;
}
return OK;
}

//创建无向图
int CreateUDG(MGragh *M)
{
int i,j,k;
int weight=1;
VertexType v1,v2;
printf("输入无向网的顶点数和弧数:\n");
scanf_s("%d%d",&M->vexnum,&M->arcnum);
//初始化邻接矩阵
for(i=0;i<M->vexnum;i++)
for(j=0;j<M->vexnum;j++)
M->arcs[i][j].adj=0;//初始所有点不相邻
printf("输入图的%d个顶点:\n",M->vexnum);
for(i=0;i<M->vexnum;i++)
scanf_s("%d",&M->vexs[i]);
printf("建立弧,请输入%d条弧的顶点:\n",M->arcnum);
for(k=0;k<M->arcnum;++k)
{
scanf_s("%d%d",&v1,&v2);
i=LocateVex(M,v1);
j=LocateVex(M,v2);
if(i<0||j<0)
return ERROR;
M->arcs[i][j].adj=weight;
M->arcs[j][i].adj=M->arcs[i][j].adj;//无向的
}
return OK;
}
//返回V的第一个邻接顶点
int FirstAdjVex(MGragh *G,int v)
{
int i;
for(i=0;i<G->vexnum;i++)
if(G->arcs[v][i].adj!=0)
return i;
return -1;
}
//返回V的相对于W的下一个邻接顶点
int NextAdjVex(MGragh *G,int v,int w)
{
int i;
for(i=w+1;i<G->vexnum;i++)
if(G->arcs[v][i].adj!=0)
return i;
return -1;
}

//广度遍历邻接矩阵
void BFSTraverse(MGragh *G)
{

int v,u,w;
int b=0;
SQueue Q;
printf("广度遍历:\n");
for(v=0;v<G->vexnum;++v)
visited[v]=0;
InitQueue(&Q);
for(v=0;v<G->vexnum;++v)
{
if(!visited[v])
{
visited[v]=1;
printf("%d ",G->vexs[v]);//visit[v]
EnQueue(&Q,v);
while(!QueueEmpty(&Q))
{
DeQueue(&Q,&u);
for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))
if(!visited[w])
{
visited[w]=1;
printf("%d ",G->vexs[w]);//visit[w]
EnQueue(&Q,w);
}//if
}//while
}//if
}
printf("\n");
}

void DFS(MGragh *G,int v0)
{
int vj;
printf("%d ",G->vexs[v0]);
visited[v0]=1;
for(vj=0;vj<G->vexnum;vj++)
{
if(!visited[vj]&&G->arcs[v0][vj].adj!=0)
DFS(G,vj);
}
}

//深度遍历
void  DFSTaverse(MGragh *G)
{
int vi;
printf("深度遍历:\n");
for(vi=0;vi<G->vexnum;vi++)
visited[vi]=0;
for(vi=0;vi<G->vexnum;vi++)
if(!visited[vi])
DFS(G,vi);
printf("\n");
}

//输出邻接矩阵
void PrintMatrix(MGragh *G)
{
int i,j;
printf("邻接矩阵为:\n");
for(i=0;i<G->vexnum;i++)
{
for(j=0;j<G->vexnum;j++)
printf("%d ",G->arcs[i][j].adj);
printf("\n");
}
}

//添加一个顶点
void InsertVex(MGragh *G,VertexType v)
{
int i,j;
printf("添加一个顶点 %d\n",v);
G->vexnum++;
G->vexs[G->vexnum-1]=v;
i=LocateVex(G,v);
for(j=0;j<G->vexnum;j++)
{
G->arcs[i][j].adj=0;//添加的顶点默认和其他顶点不邻接
G->arcs[j][i].adj=0;
}
}
//删除一个顶点
int DeVex(MGragh *G,VertexType v)
{
int i,j;
printf("删除顶点%d\n",v);
i=LocateVex(G,v);
if(i==-1)
{
printf("点%d不在该图中\n",v);
return ERROR;
}
for(j=0;j<G->vexnum;j++)
{
G->arcs[i][j].adj=0;
G->arcs[j][i].adj=0;//删除与该顶点连接的弧
}
for(j=i;j<G->vexnum;j++)
G->vexs[j]=G->vexs[j+1];
G->vexnum--;
return OK;
}

//添加一条弧
int InserArc(MGragh *G)
{
VertexType v1,v2;
int weight;
int i,j;
printf("添加一条弧\n");
if(G->Graphkind==1||G->Graphkind==3)//图,权重为1
{
printf("输入要添加的弧的两个顶点:\n");
scanf_s("%d%d",&v1,&v2);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
if(i==-1||j==-1)
{
printf("顶点不在图中\n");
return ERROR;
}
if(G->Graphkind==1)//有向图
G->arcs[i][j].adj=1;
else//无向图
G->arcs[i][j].adj=G->arcs[j][i].adj=1;
}
if(G->Graphkind==2||G->Graphkind==4)//网,有权重
{
printf("输入要添加的弧的两个顶点和权重:\n");
scanf_s("%d%d%d",&v1,&v2,&weight);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
if(i==-1||j==-1)
{
printf("顶点不在图中\n");
return ERROR;
}
if(G->Graphkind==2)//有向网
G->arcs[i][j].adj=weight;
else//无向网
G->arcs[i][j].adj=G->arcs[j][i].adj=weight;
}
return OK;

}

//删除一条弧
int DeArc(MGragh *G)
{
int i,j;
VertexType v1,v2;
printf("删除一条弧\n");
printf("输入要删除的弧的两个节点:\n");
scanf_s("%d%d",&v1,&v2);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
if(i==-1||j==-1)
{
printf("顶点不在该图中\n");
return ERROR;
}
if(G->Graphkind==1||G->Graphkind==2)//有向的
G->arcs[i][j].adj=0;
if(G->Graphkind==3||G->Graphkind==4)//无向的
G->arcs[i][j].adj=G->arcs[j][i].adj=0;
return OK;
}
//创建图的选择函数,在main中调用
int CreatGragh(MGragh *G)
{
printf("输入要建立的图的类型:\n");
printf("1:有向图 2:有向网 3:无向图 4:无向网\n");
scanf_s("%d",&G->Graphkind);
switch(G->Graphkind)
{
case 1:return CreateDG(G);
case 2:return CreateDN(G);
case 3:return CreateUDG(G);
case 4:return CreateUDN(G);
default:return ERROR;
}
}
///////////////////////////////////////与队列有关的操作/////////////////////////////////////////////////////////////
void InitQueue(SQueue *Q)
{
Q->base=(VertexType *)malloc(QM*sizeof(VertexType));
if(!Q->base)exit(0);
Q->front=Q->rear=0;
}

void EnQueue(SQueue *Q,int e)
{
if((Q->rear+1)%QM==Q->front) exit(0);
Q->base[Q->rear]=e;
Q->rear=(Q->rear+1)%QM;
}

int QueueEmpty(SQueue *Q)
{
if(Q->front==Q->rear)
return 1;
return 0;
}

void DeQueue(SQueue *Q,int *e)
{
if(Q->front==Q->rear)exit(0);
*e=Q->base[Q->front];
Q->front=(Q->front+1)%QM;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

数据结构 图的基本操作实现

实验题目: 图的基本操作实现                实验环境:   Visual C++ 6.0                     实验目的:掌握图的邻接矩阵和邻接表两个存储结构及表示。...
  • yao1373446012
  • yao1373446012
  • 2016年11月07日 17:28
  • 2953

数据结构之图的实现

本文主要包括以下内容 邻接矩阵实现无向图 邻接表实现无向图 邻接矩阵实现有向图 邻接表实现有向图 图的理论基础,请参考:图的理论基础 - 如果天空不死 - 博客园邻接矩阵实现无向图Mat...
  • whuhan2013
  • whuhan2013
  • 2016年06月25日 21:35
  • 5073

数据结构(16)--图的存储及实现

参考书籍:数据结构(C语言版)严蔚敏吴伟民编著清华大学出版社         图状结构是一种比树形结构更复杂的非线性结构。在树状结构中,结点间具有分支层次关系,每一层上的结点只能和上一层中的至多一个结...
  • u010366748
  • u010366748
  • 2016年03月03日 18:28
  • 5046

数据结构:图的实现--邻接表

当图中的边数较少时,用邻接表来实现图结构,则会浪费很多内存空间。因此,考虑另一种实现图结构的方法:邻接表。在邻接表中主要有两种节点结构体:...
  • zhangxiangDavaid
  • zhangxiangDavaid
  • 2014年08月01日 01:02
  • 5639

数据结构图的实现

  • 2008年06月19日 12:25
  • 4KB
  • 下载

数据结构——图(1),图的存储结构Java实现

图概述图是一种重要的数据结构,基本概念包括:顶点,边,有向,无向,权,路径回路,连通域,邻接点,度,入边,出边,入度,出度等等,很好理解,不赘述,可以参考这篇博客:http://www.cnblogs...
  • picway
  • picway
  • 2017年03月29日 21:45
  • 2652

数据结构图的邻接矩阵,邻接表存储表示,图的深度优先搜索遍历,广度优先搜索遍历

  • 2010年06月17日 21:58
  • 2KB
  • 下载

图的邻接矩阵的建立(C语言实现)

#include #include typedef char VertexType; typedef int EdgeType; #define MAXVEX 100 #define INFINI...
  • u013291337
  • u013291337
  • 2015年05月08日 18:22
  • 4038

【数据结构】图的构建(邻接表法)

最近整理电脑,发现了以前写的数据结构的代码,由于时间久了,好多代码都找不到了,现在扒出来复习一下。 如果看不懂下面关于图的术语或者压根就不知道图。建议看一下严蔚敏版的《数据结构》中对图的介绍 ...
  • sundong_d
  • sundong_d
  • 2015年04月10日 19:12
  • 9602

数据结构:图的实现--邻接表

图的实现:邻接表 当图中的边数较少时,用邻接表来实现图结构,则会浪费很多内存空间。因此,考虑另一种实现图结构的方法:邻接表。在邻接表中主要有两种节点结构体: 顶点节点 边...
  • wsxsd94
  • wsxsd94
  • 2014年08月10日 12:56
  • 404
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构的C实现_图_邻接矩阵表示
举报原因:
原因补充:

(最多只允许输入30个字)