数据结构的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;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

相关文章推荐

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

#include #include typedef char VertexType; typedef int EdgeType; #define MAXVEX 100 #define INFINI...

图的邻接矩阵c语言表示(无向网)---《数据结构》算法7.2

邻接矩阵是图的一种表示法,构造具有n个顶点和e条边的无向网G的时间复杂度为(n^2+e*n),代码如下:#include #define infinity 2000000000 #define MAX...

【c/c++ 算法/数据结构】 邻接矩阵表示图,深度,广度优先遍历 算法设计+代码+图片

*问题描述: 建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选两种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。   1、邻接矩阵...
  • wzwdcld
  • wzwdcld
  • 2014年05月24日 15:15
  • 2997

数据结构--图的邻接矩阵表示法

  • 2013年07月17日 18:36
  • 56KB
  • 下载

数据结构之图(C++)--邻接矩阵表示(一)

数据结构之图(C++)–邻接矩阵表示(一)基本概念简单地说,图是一个用线或边链接爱一起的顶点或节点的集合。严格地说,图是有限集V和E的有序对,即G=(V,E),其中V的元素称为顶点(也称节点或点),E...
  • tutuxs
  • tutuxs
  • 2016年11月18日 23:06
  • 312

数据结构——求邻接矩阵表示的图的关节点

#include using namespace std; #include #include #define OK 1 #define NULL 0 #define MAX...

【数据结构】邻接矩阵表示法的图的深度广度优先遍历递归和非递归遍历

假设有以下结构的图: 用邻接矩阵表示如下: 因为他是无向图,我们可以发现他的矩阵是对角对称的。矩阵中每一行每一列都可以看成是一个顶点,矩阵中的元素表示着该顶点与其他顶点的关系,当元素的值为1说明...
  • e_one
  • e_one
  • 2016年02月02日 16:26
  • 7023

C++面向对象的数据结构之 图(邻接矩阵表示)

图是由顶点集合(Vertex)及顶点间的关系集合组成的一种非线性数据结构。加上一些基本操作即构成了抽象的数据类型(现只介绍无向图)。其接口如下: 分为几个方面 1.图的基本概念2.图的存储结构...

详解数据结构——图之邻接矩阵表示法

一、图的建立 图是表达“多对多”的关系的一种数据结构。 它由非空的有限顶点集合和有限边集合组成。 1. 顶点集合常常由数组表示。 数组下标表示顶点位置。 数组内容包含顶点数据,并且要...
  • Van0512
  • Van0512
  • 2016年10月29日 22:54
  • 381

数据结构-图的邻接矩阵表示

图的邻接矩阵表示这里仅实现了UDG(无向图)的输入,有向图,有向网,无向网自己照葫芦画瓢。// Graph_in_adjacent_matrix.h #ifndef GRAPH_IN_ADJACENT...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构的C实现_图_邻接矩阵表示
举报原因:
原因补充:

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