无向图的邻接矩阵表示求各顶点的度-----数据结构与算法笔记

📚参考书:《数据结构(C语言)》–严蔚敏等编著,清华大学出版社。

📖图

(graph)是一种较线性表和树更为复杂的数据结构,在图型结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都可以相互关联。
在生活中最具有代表性的图就是我们所用的地图,每个城市代表着一个顶点,城市之间的关系多种多样,且图可分为有向图和无向图,如下:
在这里插入图片描述
图的相关术语:
顶点:图中的数据元素称为顶点;

  • 有向图中V1到V2称为一条弧:<v1,v2> ;
  • 无向图中V1到V2称为一条边:(v1,v2);

弧尾:称v1为弧尾(或初始点);
弧头:称v2为弧头(或终端点);
完全图:有 1 2 n ( n − 1 ) \bf\color{teal}\dfrac{1}{2}n\left( n-1\right) 21n(n1) 条边的无向图称为完全图;
有向完全图 n ( n − 1 ) \bf\color{teal}n\left( n-1\right) n(n1) 条弧的有向图称为有向完全图;
稀疏图:有很少条边或弧(如 e < n log ⁡ n \bf\color{teal}e<n\log{n} e<nlogn)的图称为稀疏图;
稠密图:稀疏图反之为稠密图;
:有时图的边或者弧具有与它相关的数,这种图的边或弧相关的数称为权;
:带的图称为网;
顶点的度:是指和该顶点相连的边数,如上无向图顶点V1的度为:3
顶点的出度:是指以该顶点为尾的边数,如上有向图顶点V1的出度为:2
顶点的入度:是指以该顶点为头的边数,如上有向图顶点V1的入度为:1

😄 在无向图中,任意两个顶点之间都是连通的,则称为连通图(无向图),非连通图和连通图如下区分:
在这里插入图片描述
连通分量:是指无向图中的极大连通子图,如下非连通图有3个连通分量:
在这里插入图片描述
😄 在有向图中,对于每一对vi,vj(vi != vj),从vi到vj和vj到vi都存在路劲,则称为强连通图(有向图),有向图中的极大强连通子图称为有向图的强连通分量。

🍵 生成树:一个连通图的生成树是一个极小连通子图,它含有全部顶点,但只有足以构成一棵树的n-1条边。

🌔 重点:
🍊 一棵有n个顶点的生成树有且仅有n-1条边。
🍊 如果多于n-1条边,必构成环(回路)。
🍊 有n-1条边的图不一定是生成树。
🍊 一个图有n个顶点和小于n-1条边,则图为非连通图

📖 图的存储结构

🍋 图的数组表示法(邻接矩阵表示)

#define INFINITY	INT_MAX	//最大值∞
#define MAX_VERTEX_NUM 20 //最大顶点数
typedef enum {DG,DN,UDG,UDN} GraphKind; //有向图,有向网,无向图,无向网
typedef struct ArcCell {
	VRType adj;	//VRType是顶点关系类型,多于无权图用1或0表示,表示相邻否,对于有权图则为权值
	InfoType *info; //该弧相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct {
	VertexType vexs[MAX_VERTEX_NUM];	//顶点向量
	AdjMatrix arcs;	//邻接矩阵
	int vexnum, arcnum;	//当前顶点数和弧数
	GraphKind kind;	//图的种类
}MGraph;

🍋 邻接矩阵(数组)表示图的优点:
🍎 直观,简单,好理解;
🍎 方便检查任意一对顶点是否存在边;
🍎 方便找任意一顶点的所有的"邻接点";
🍎 方便计算任意顶点的度;

🍋 邻接矩阵(数组)表示图的缺点:
🍎 不方便增加和删除顶点;
🍎 浪费空间----存稀疏图有大量0元素;
🍎 浪费时间----统计稀疏图共有多少条边;

🔗 相关代码:

#include "stdio.h"
#include "stdlib.h"
#define TRUE     1
#define FALSE    0
#define OK       1
#define ERROR    0
#define OVERFLOW -2
#define INFINITY INT_MAX	//最大值 
#define MAX_VERTEX_NUM 20	//最大顶点数 

typedef int Status;
typedef int VertexType;
typedef int ArcType;
typedef struct {
	VertexType	vexs[MAX_VERTEX_NUM];				//顶点向量
	ArcType	arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];	//邻接矩阵
	int vexnum,arcnum;		//图的当前顶点数和弧数
} MGraph;

Status LocateVex(MGraph G,VertexType v);
//定位v在邻接矩阵中的位置
Status LocateVex(MGraph G,VertexType v) {
	int i;
	for(i=0; i<G.vexnum; i++) {
		if(G.vexs[i]==v) return i;
	}
	return -1;
}

Status CreateUDGraph(MGraph &G);
//构造邻接矩阵表示的无向图 UDG
Status CreateUDGraph(MGraph &G) {
	printf("请输入当前顶点数和弧数(空格隔开):");
	scanf("%d %d",&G.vexnum,&G.arcnum);
	int i,j,k;
	int v1,v2;	//弧尾和弧头 
	for(i=0; i<G.vexnum; i++) {
		printf("请输入第%d个的顶点信息:",i+1);
		scanf("%d",&G.vexs[i]);
	}
	printf("\n");
	for(i=0; i<G.vexnum; i++) 	//初始化邻接矩阵
		for(j=0; j<G.vexnum; j++) {
			G.arcs[i][j]= {INFINITY};	
		}
	for(k=0; k<G.arcnum; k++) {
		printf("请输入第%d条边的起点序号和终点序号(空格隔开):",k+1);
		scanf("%d %d",&v1,&v2);
		i=LocateVex(G,v1);
		j=LocateVex(G,v2);
		if(i==-1 || j==-1) return ERROR;
		else {
			G.arcs[i][j]=1;
			G.arcs[j][i]=1;
		}
	}
	return OK;
}

Status PrintUDGraph(MGraph G);
//打印图
Status PrintUDGraph(MGraph G) {
	int i,j;
	printf("\n无向图的顶点为:\n");
	for(i=0; i<G.vexnum; i++)
		printf("%d ",G.vexs[i]);
	printf("\n无向图的邻接矩阵为:\n");
	printf("\t");
	for(i=0; i<G.vexnum; ++i)
		printf("%8d", G.vexs[i]);
	putchar('\n');
	for(i=0; i<G.vexnum; ++i) {
		printf("\n%8d", G.vexs[i]);
		for(j=0; j<G.vexnum; ++j) {
			if(G.arcs[i][j] == INT_MAX) printf("%8s", "0");
			else printf("%8d",G.arcs[i][j]);
		}
		printf("\n");
	}
	return OK;
}

Status Degree(MGraph G);
//求无向图各顶点的度
Status Degree(MGraph G) {
	int i,j, deg;
	for(i=0; i<G.vexnum; i++) {
		deg=0;	//初始为0
		for(j=0; j<G.vexnum; j++) {
			if(G.arcs[i][j]  != INT_MAX) {
				deg++;
			}
		}
		if(deg == 0)  printf("\n顶点%d没有度\n",G.vexs[i]);
		else printf("\n顶点%d的度为:%d\n",G.vexs[i],deg);
	}
}

int main(void) {
	MGraph G;
	CreateUDGraph(G);
	PrintUDGraph(G);
	putchar('\n');
	Degree(G);
	return 0;
}

实现:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

24:

谢谢,只求点赞哟

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

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

打赏作者

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

抵扣说明:

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

余额充值