数据结构——图的邻接矩阵存储

本文介绍图的邻接矩阵存储方式及其基本操作,包括深度优先遍历、广度优先遍历、求节点度、判断图是否连通及求最小生成树等算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构——图的邻接矩阵存储

功能实现

图的邻接矩阵的储存 (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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃冰粉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值