数据结构——图的邻接矩阵存储
功能实现
图的邻接矩阵的储存 (1)深度优先遍历 (2)广度优先遍历 (3)求结点的度 (4)判断图是否连通 (5)求最小生成树 (6)退出
#include<stdio.h>
#include<stdlib.h>
#define maxvex 20
#define Maxsize 50
#define maxInt 32767
typedef struct Graphnode{
char Vexs[maxvex]; //顶点表
int arcs[maxvex][maxvex]; //邻接矩阵
int vexnum,arcnum; //图的当前点数和边数
}MGraph;
int visited[maxvex];//辅助数组 visited [n]
// 查找顶点表中的顶点并且返回顶点的下标
int Locatvex(MGraph *G,char u){
int i;
for(i=0;i<G->vexnum;i++){
if(u==G->Vexs[i]){
return i;
}
}
return -1;
}
void createMGraph(MGraph *G){
printf("请输入总顶点数和总边数:\n");
scanf("%d%d",&G->vexnum,&G->arcnum);
getchar();
printf("请输入顶点的信息:\n");
int i,j,k;
for(i=0;i<G->vexnum;i++)
scanf("%c",&G->Vexs[i]);
getchar();
//初始化邻接矩阵,使每个权值初始化为极大值。
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
G->arcs[i][j]=maxInt;
char v1,v2;
int d;
printf("请输入相关边关联的顶点和边上的权值:\n");
for(k=0;k<G->arcnum;k++){
scanf("%c%c%d",&v1,&v2,&d);
getchar();
i=Locatvex(G,v1);
j=Locatvex(G,v2);
G->arcs[i][j]=d;
G->arcs[j][i]=G->arcs[i][j];
}
}
//深度优先遍历
void DFS(MGraph *G,int v){
printf("%c ",G->Vexs[v]);
visited[v]=1;
int w;
for(w=0;w<G->vexnum;w++){
if(G->arcs[v][w]!=maxInt&&visited[w]==0)
DFS(G,w);
}
}
void DFSMGraph(MGraph *G){
int i;
for(i=0;i<G->vexnum;i++){
visited[i]=0;
}
for(i=0;i<G->vexnum;i++){
if(visited[i]==0)
DFS(G,i);
}
}
typedef struct{
int *base; //初始化的动态分配存储空间
int front; //头指针,若队列不空,则指向队列头元素
int rear;//尾指针,若队列不空,则指向队列尾元素的下一个位置
}Sequeue;
//构造一个空的队列
void InitQueue(Sequeue *Q){
Q->base=(int *)malloc(Maxsize*sizeof(int));
if(!Q->base)
exit(0);
Q->front=Q->rear=0;
}
//返回队列Q的元素的个数,即队列的长度
int QueueLength(Sequeue *Q){
return(Q->rear -Q->front+Maxsize)%Maxsize;
}
//插入元素e为Q的新的队尾元素
void EnQueue(Sequeue *Q,int e){
if((Q->rear+1)%Maxsize==Q->front){
printf("The queue is full!\n");
return;
}
Q->base[Q->rear]=e;
Q->rear=(Q->rear +1)%Maxsize;
}
//若队列不为空,则删除Q的对头元素,用e返回其值
void DeQueue(Sequeue *Q,int *e){
if(Q->front ==Q->rear){
printf("The queue is empty!\n");
return;
}
*e=Q->base[Q->front];
Q->front=(Q->front +1)%Maxsize;
}
int IsEmpty(Sequeue *Q){
if(Q->front==Q->rear)
return 1;
else
return 0;
}
void BFS(MGraph *G,int v){
Sequeue Q;
int is;
printf("%c ",G->Vexs[v]);
visited[v]=1;
int u,w;
//创建队列
InitQueue(&Q);
//入队
EnQueue(&Q,v);
is=IsEmpty(&Q);
while(is==1){
DeQueue(&Q,&u);//出队
for(w=0;w<G->vexnum;w++){
if(G->arcs[v][w]!=maxInt&&visited[w]==0){
printf("%c ",G->Vexs[w]);
visited[w]=1;
EnQueue(&Q,w);
}
}
}
}
void BFSMGraph(MGraph *G){
int i;
for(i=0;i<G->vexnum;i++){
visited[i]=0;
}
for(i=0;i<G->vexnum;i++)
{ if(visited[i]==0)
BFS(G,i);}
}
//求节点的度
void MGraphTD(MGraph *G){
int i,j;
int vexArray[maxvex] = {0};
for(i = 0;i < G->vexnum;i++){
for(j = 0;j < G->vexnum;j++){
if(G->arcs[i][j] != maxInt){
vexArray[i]++;
}
}
printf("此结点%c的度为:%d\n",G->Vexs[i],vexArray[i]);
}
}
//判断图是否连通
// 输入一个点通过深度优先遍历它能够一次就输出全部顶点就为连通
void isConnection(MGraph *G){
int i;
int j =0;//接收顶点的下标
char v;
int isFlag = 0;
for(i=0;i<G->vexnum;i++){
visited[i]=0;
}
printf("请输入一个顶点\n");
getchar();
scanf("%c",&v);
getchar();
j = Locatvex(G,v);//返回顶点的下标
if(i != -1){
DFS(G,j);
}
//用来判断是否一次就能把整个图遍历完
for(i=0;i<G->vexnum;i++){
if(visited[i] == 1){
isFlag++;
}
}
printf("%d\n",isFlag);
if(isFlag == G->vexnum){
printf("这个图是一个连通图\n");
} else{
printf("这个图不是一个连通图\n");
}
}
//求最小生成树
void Prim(MGraph *G){ //g为连通图,v为起点
char vex;
int v; //接收顶点的下标
printf("请输入一个顶点\n");
getchar();
scanf("%c",&vex);
getchar();
v = Locatvex(G,vex);//返回顶点的下标
int lowcost[maxvex];
int min;
int closest[maxvex],i,j,k;
for (i=0;i< G->vexnum;i++){ //给lowcost[]和closest[]置初值
lowcost[i]=G->arcs[v][i];
closest[i]=v;
}
lowcost[v]=0;
for (i=1;i<G->vexnum;i++){ //输出(n-1)条边
min=maxInt;
for (j=0;j<G->vexnum;j++){ //在(V-U)中找出离U最近的顶点k
if (lowcost[j]!=0 && lowcost[j]<min){
min=lowcost[j];
k=j; //k记录最近顶点编号
}
}
printf(" 边(%d,%d)权为:%d\n",closest[k],k,min);
lowcost[k]=0; //标记k已经加入U
for (j=0;j<G->vexnum;j++) //修改数组lowcost和closest
if (lowcost[j]!=0 && G->arcs[k][j]<lowcost[j]){
lowcost[j]=G->arcs[k][j];
closest[j]=k;
}
}
}
int main(){
int choice;
MGraph G;
while(1){
printf("**********图的相关操作(顺序存储)**********\n");
printf(" 1.图的邻接矩阵的储存.\n");
printf(" 2.深度优先遍历.\n");
printf(" 3.广度优先遍历.\n");
printf(" 4.求结点的度.\n");
printf(" 5.判断图是否连通.\n");
printf(" 6.求最小生成树.\n");
printf(" 0.退出.\n");
printf(" 请输入你的选择..\n");
scanf("%d",&choice);
if(choice==0)
break;
switch(choice){
case 1:
printf("******现在开始生成领接矩阵*****\n");
createMGraph(&G);
break;
case 2:printf("深度优先遍历结果是:");
DFSMGraph(&G);
printf("\n");
break;
case 3:printf("广度优先遍历结果是:");
BFSMGraph(&G);
printf("\n");
break;
case 4:
MGraphTD(&G);
break;
case 5:
isConnection(&G);
break;
case 6:
Prim(&G);
break;
}
}
return 0;
}