數據結構的C實現_圖_鄰接矩陣表示

//編譯環境 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;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章