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

来源:互联网 发布:c语言比大小 编辑:程序博客网 时间:2024/04/29 16:58
//编译环境 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 0int 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;}///////////////////////////////////////////////////////////////////////////////////////////////////

原创粉丝点击