关闭

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

标签: 数据结构cstruct
3033人阅读 评论(0) 收藏 举报
分类:
//编译环境 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;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

1
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:181174次
    • 积分:2146
    • 等级:
    • 排名:第18306名
    • 原创:37篇
    • 转载:13篇
    • 译文:0篇
    • 评论:55条
    文章分类
    最新评论