图的存储结构01—数组表示法

本文介绍了图的数组表示法,即邻接矩阵,详细阐述了如何用C语言实现邻接矩阵,并分析了构造函数的时间复杂度。邻接矩阵适用于快速判断两个节点是否相邻,以及求解节点的度。

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

图的数组(邻接矩阵)存储表示

  • 代码实现(C语言)
  • 定义邻接矩阵
// ----- 图的数组(邻接矩阵)存储表示 -----
typedef int VRType;  //顶点关系类型,无权图用1或0表示相邻否,带权图则为权值类型 
typedef char* InfoType;  //弧/边相关信息
typedef int VertexType; 
#define INFINITY INT_MAX  //最大值∞
#define MAX_VERTEX_NUM 20  //最大顶点个数
typedef enum{DG,DN,UDG,UDN}GraphKind;  //{有向图,有向网,无向图,无向网}
typedef struct ArcCell{
	VRType adj;  // 顶点关系类型
	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;
  • 邻接矩阵表示法图示
边/弧结构体(struct ArcCell)示意

adj

标记图中此弧/边是否相连或此弧/边的权值 

Info

指向与此边相关的信息的指针

 

 

 

邻接矩阵AdjMatrix(假设有最大结点数为3)

ArcCell(0 0)

一号结点到一号结点的环

ArcCell(0 1)

一号结点到二号结点的弧/边

ArcCell(0 2)

一号结点到三号结点的弧/边

ArcCell(1 0)

二号结点到一号结点的弧/边

ArcCell(1 1)

二号结点到二号结点的环

ArcCell(1 2)

二号结点到三号结点的弧/边

ArcCell(2 0)

三号结点到一号结点的弧/边

ArcCell(2 1)

三号结点到二号结点的弧/边

ArcCell(2 2)

三号结点到三号结点的环

 

 

 

 

 

 

 

图的结构体MGraph

vexs数组

记录结点信息

arcs邻接矩阵

记录弧/边

vexnum,arcnum

图的结点数&弧/边数

kind

有向图/有向网/无向图/无向网

 

 

 

 

  • 图的构造函数
#define OK 1
#define ERROR 0
typedef int Status;
Status CreateGraph(MGraph* G)
{
	scanf("%d",&G->kind);
	switch (G->kind)
	{
		case DG:return CreateDG(G);
		case DN:return CreateDN(G);
		case UDG:return CreateUDG(G);
		case UDN:return CreateUDN(G);
		default:return ERROR; 
	}
}
// 无向网构造函数
Status CreateUDN(MGraph *G)
{
	int IncInfo;
	int i,j,k;
	int v1,v2,weight;
	scanf("%d %d %d",&G->vexnum,&G->arcnum,&IncInfo);  // IncInfo为0则各边不含其他信息 
	for (i=0;i<G->vexnum;i++)
		scanf("%d",&G->vexs[i]);  //构造顶点向量(约定第一个结点为1,...第n个节点为n)
	for (i=0;i<G->vexnum;i++)  // 初始化邻接表
		for (j=0;j<G->vexnum;j++)
			{
				G->arcs[i][j].adj=INFINITY;  // adj=INFINITY表示不存在边
				G->arcs[i][j].info=NULL;  // 每条弧/边不存在额外信息,指针初始化为NULL
			}
	for (k=0;k<G->arcnum;k++)  // 更新边信息
	{
		scanf("%d %d %d",&v1,&v2,&weight);  // 输入边连接的两点以及此边的权值
		i=v1-1;j=v2-1;  // 第v1个结点到第v2个结点的边在邻接表中的位置
		G->arcs[i][j].adj=weight;  // 为边赋权
		if (IncInfo) scanf("%s",G->arcs[i][j].info);  // 若边存在额外信息,输入额外信息
		G->arcs[j][i]=G->arcs[i][j]; // 无向图,将边双向化
	}
	return OK;
} // CreateUDN

/*有向图/网以及无向图的构造函数算法与上述无向网构造函数类似,仅需要在双向化&为边/弧赋权处略作改动即可*/ 

 

 

  • 构造函数的时间复杂度分析(n条边&e个顶点)
  1. 初始邻接表O(n^2)
  2. 输入结点信息O(e)
  3. 输入边信息O(n)
  4. T(n)=O(n^2)

应用场景

  1. 通过邻接表容易判断两结点是否邻接O(1)
  2. 容易求各个结点的度O(e)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值