图的存储结构及实现02

常用的图的存储结构有邻接矩阵、邻接表、十字链表和邻接多重表。
在这里插入图片描述

  1. 图的数组表示法——邻接矩阵

图的逻辑结构分为顶点集合和边的集合两部分,一个顶点是一个元素,因此可以用一个一维数组存放顶点数据;一条边是用其关联的两个顶点表示的,即一个边元素有两个数据域,因此可以用一个矩阵存放顶点间的邻接关系(即边或弧),这个二维数组也被称为邻接矩阵。如果两个顶点是关联的,那么矩阵的值可以记为1,否则记为0。
在这里插入图片描述
邻接矩阵的定义
在这里插入图片描述
(1) 无向图邻接矩阵
在这里插入图片描述
(2)有向图邻接矩阵
在这里插入图片描述
(3)网的邻接矩阵
在这里插入图片描述
邻接矩阵数据结构描述

(1)结构描述

#define  VERTEX_NUM  6        //图的顶点数
#define  VERTEX_MAX_NUM 64   //图的最大顶点数
#define  EDGE_MAX_NUM  20   //图的最大边数
typedef char VexType;   //顶点的数据类型
typedef int InfoType;   // 弧(边)的类型,如权值、边存在或不存在等

邻接矩阵 Adjacency Matrix——AM

typedef struct
{   VexType  VertexArray[VERTEX_NUM];  //顶点数组
    InfoType  AdjMatrix [VERTEX_NUM][ VERTEX_NUM];  //邻接矩阵
} AM_Graph;

(2)邻接矩阵复杂度分析
在这里插入图片描述
2. 边集数组表示法

(1)边集数组的设计
边集数组只存储图中所有边(或弧)的信息,存储一条边的起点、终点(对于无向图,可选定边的任一端点为起点或终点)和边的相关信息(如权值),各边在数组中的次序可任意安排,也可根据具体要求而定。若需存储顶点信息,还需一个 VERTEX_NUM 个元素的一维数组。
在这里插入图片描述
(2)边集数组 (Edgeset Array)的数据结构描述

typedef  struct  //边集数组单元结构
{   VexType  from_vex;  //起点
    VexType  end_vex;  //终点
    InfoType  weight;  //权值项可以根据需要设置
} EdgeStruct;
EdgeStruct  EdgeSet[EDGE_MAX_NUM];  //边集数组

(3)边集数组的复杂度分析
在这里插入图片描述
3. 图的链表表示法 1 ——邻接表

邻接矩阵排列直观容易理解,若图结构本身需要在解决问题的过程中动态地产生,则每增加或删除一个顶点都需要改变邻接矩阵的大小,这样做的效率显然是很低的。除此之外,邻接矩阵占用的存储单元数目只与图中顶点的个数有关,而与边(弧)的数目无关,对于边数相对顶点较少的稀疏图,这种存储结构空间浪费较大。

(1)邻接表的存储结构设计
对图的每个顶点建立一个单链表( n 个顶点建立 n 个单链表),第 i 个单链表中的结点包含顶点 Vi 的所有邻接结点。
对 n 个同类单链表并行管理,是采用“带行向量的链表表示方法”,这种存储结构称为邻接表。邻接表由头结点表和邻接结点链表两部分组成。

无向图邻接表
在这里插入图片描述
对于无向图来说,使用邻接表进行存储也会出现数据冗余,头结点 V1 所指链表中存在一个指向 V4 的邻接结点的同时,头结点 V4 所指链表也会存在一个指向 V1 的邻接结点。

有向图邻接表(出边表)
在这里插入图片描述
逆邻接表(入边表)

有时为了便于确定顶点的入度或以顶点为弧头的弧,可以建立一个有向图的逆邻接表。
在这里插入图片描述
带权邻接表

数据结构与邻接表基本一致,只在邻接结点中增加一个记录边的权值的数据域。
在这里插入图片描述
(2)邻接表数据结构描述
在这里插入图片描述
邻接表Adjacency List——AL

typedef struct AdjNode  //邻接结点结构
{     
   int adjvex;        //邻接点
   AdjNode *next;   // 邻接点指针
} AL_AdjNode; 

typedef struct  //邻接表顶点结点结构
{             
   VexType  vertex;   //顶点
   AdjNode *link;     // 邻接点头指针
} AL_VexNode; 

typedef struct  //总的邻接表结构
{                 
   A_VexNode  VexList[VERTEX_MAX_NUM];  //顶点表
   int VexNum, ArcNum;    //顶点数,弧(边)数
} AL_Graph; 

建立邻接表

/*==========================================
函数功能:建立邻接表
函数输入:无
函数输出:无
共享数据:图的邻接矩阵
=============================================*/
void Create_AdjList()
{
	AL_VexNode VexList[N]={0,NULL};  //顶点表
	int j;
	AL_AdjNode *Ptr,*nextPtr;
?
	for(int i=0; i<N; i++)
	{
		VexList[i].vertex=i;
		VexList[i].link=NULL;
		j=0;
		while(j<N)
		{
			if (AdjMatrix[i][j]!=0)//有邻接点
			{
				Ptr=(AL_AdjNode*)malloc(sizeof(AL_AdjNode));
				Ptr->adjvex=j;
				Ptr->next=NULL;
				if (VexList[i].link==NULL)//首次加入邻接点
				{
					VexList[i].link=Ptr;
				    nextPtr=Ptr;
				}
				else 
				{
					nextPtr->next=Ptr;
					nextPtr=Ptr;
				}
			}
			j++;
		}
	}
}

邻接表的空间复杂度分析
在这里插入图片描述
4. 十字链表

图的十字链表是有向图的另一种链式存储结构。该结构以入弧和出弧为线索,将有向图的邻接表和逆邻接表结合起来得到的,有顶点表和边表组成。十字链表结构也可以理解为将行的单链表和列的单链表结合起来存储稀疏矩阵,每个结点表示一个非零元素。

在十字链表中,对应于有向图中每一条弧都有一个弧结点,对应于每个顶点也有一个顶点结点。
在这里插入图片描述
在这里插入图片描述
十字链表复杂度分析
在这里插入图片描述
5. 邻接多重表

邻接多重表的存储结构和十字链表类似,也是由顶点表和边表组成,邻接多重表中,每一条边的信息用一个结点描述,一条边对应一个边结点。边结点中除了边关联的两个顶点 ivex,jvex 外,再加上与 ivex 连接的边结点位置、与jvex 连接的边结点位置。
在这里插入图片描述
在这里插入图片描述

//邻接多重表的顶点结构
typedef   struct vnode
{     VexType   vertex;   	 //顶点信息
      struct node *firstedge; //指向第一条依附于该顶点的边
} AML_VertexNode;
//邻接多重表的顶点表
AML_VertexNode  G[VERTEX_NUM]; 
//邻接多重表的边结点结构
typedef  struct node
{   int  ivex, jvex;  		//边的两个关联点
    struct node *ilink,*jlink; //分别指向依附于ivex和jvex的下一条边
}  AML_EdgeNode;

邻接多重表复杂度分析
在这里插入图片描述
存储结构归结比较存储结构归结比较

  1. 关注顶点的存储结构
    在这里插入图片描述
  2. 关注边的存储结构
    在这里插入图片描述
  3. 图存储结构选择原则
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值