图的存储和基本操作 Graph: Storage & Basic Operation

Storage

1.邻接矩阵法

1.1 Definition

即:

  • 用一个一维数组存储图的顶点信息
  • 用一个二维数组存储图的边的信息(即顶点和顶点之间的邻接关系),这个矩阵就是邻接矩阵

对于一个结点数目为 n n n 的图 G ( V , E ) G(V,E) G(V,E) 的邻接矩阵 A A A 是一个 n × n n\times n n×n 的矩阵:
A [ i ] [ j ] = { 1 , 若 ( v i , v j ) 或 < v i , v j > 是 E ( G ) 中 的 边 0 , 反 之 A[i][j]=\begin{cases} 1,&若(v_{i},v_{j})或<v_{i}, v_{j}>是E(G)中的边\\ 0,&反之 \end{cases} A[i][j]={1,0,(vi,vj)<vi,vj>E(G)
其中, v i , v j v_{i},v_{j} vi,vj 是图中的任意两个顶点, ( v i , v j ) (v_{i}, v_{j}) (vi,vj) 对应无向图中包含这两个顶点的边, < v i , v j > <v_{i},v_{j}> <vi,vj> 对应于有向图中包含这两个顶点的边。
对于带权图来说:
A [ i ] [ j ] = { w i , j , 若 ( v i , v j ) 或 < v i , v j > 是 E ( G ) 中 的 边 0 或 ∞ , 反 之 A[i][j]=\begin{cases} w_{i,j},&若(v_{i},v_{j})或<v_{i}, v_{j}>是E(G)中的边\\ 0或\infin,&反之 \end{cases} A[i][j]={wi,j,0,(vi,vj)<vi,vj>E(G)
即相连的顶点之间用权重表示,用 0 , ∞ 0,\infin 0, 表示不相邻的顶点,则我们图的定义如下:

#define MAX_VERTEX 100
typedef struct Graph{
	int vertices[MAX_VERTEX];
	int edges[MAX_VERTEX][MAX_VERTEX];
	int vnum = 0;
	int enum = 0;
}Graph;
1.2 Characteristic

邻接矩阵法的特点:

  • 无向图的邻接矩阵一定是一个对称矩阵(并且唯一),只需存储上三角或下三角矩阵即可
  • 对于无向图,邻接矩阵第 i i i 行或者第 i i i 列的非零元素的个数即为这第 i i i 个顶点的度
  • 对于有向图,邻接矩阵的行列中的非零元素的个数分别是该顶点的出度和入度(具体对应关系取决于矩阵的定义)
  • 容易确定两点之间的相关性,但不易确定图中边数
  • 适合表示稠密图(非零元素较多)
  • 邻接矩阵 A A A A n A^{n} An 中的非零元素表示从一个顶点到另外一个顶点存在长度为 n n n 的路径

2.邻接表法

2.1 Definition

邻接表法可以用于解决邻接矩阵法在存储稀疏矩阵的时候存储空间大量浪费的问题,结合了顺序存储和链式存储的方法,首先,对所有顶点建立一个单链表:

datafirstarc

其中,data为顶点域,firstarc为边表的头指针,即包含这个顶点的所有边中除了这个顶点外的另外顶点的链表,对于有向图来说,这个链表是一个出边表,存储的是这个顶点的出边的所有边头,边表的结点如下:

datanextarc

nextarc,指向下一个该顶点的邻接顶点,即下一条边,存储结构定义如下:

#define MAX_VEX 100

class Graph{
public:
	// 边表
	typedef struct ArcNode{
		int adjv;
		ArcNode *next;
	}ArcNode;
	// 顶点表
	typedef struct VexNode{
		int v;
		ArcNode* first;
	}VexNode;
private:
	VexNode vexList[MAX_VEX];
	int vexNum, arcNum;
public:
	// operations
};
2.2 Characteristic

邻接表法具有以下特点:

  • 无向图:存储空间为 O ( ∣ V ∣ + 2 ∣ E ∣ ) O(|V|+2|E|) O(V+2E),因为每条边需要在两个顶点的边表中都出现,有向图:存储空间为 O ( ∣ V ∣ + ∣ E ∣ ) O(|V|+|E|) O(V+E),出边在每个顶点对应的边表中是唯一的
  • 存储稀疏图时可以节省大量空间
  • 容易找出顶点的所有邻边;不易确定两点是否邻接(相对于邻接矩阵法)
  • 易求出度,难求入度(需遍历整表),而在邻接矩阵法中都可以在 O ( n ) O(n) O(n) 的时间内求得
  • 邻接表不唯一,在于边表中边的次序没有规定

3.十字链表

3.1 Definition

有向图的一种链式存储方式。十字链表中,有向图每一个顶点都有一个结点:

datafirstinfirstout

其中:

  • data:结点数据
  • firstin:指向这个顶点的第一条入边对应的弧结点
  • firstout:指向这个顶点的第一条出边对应的弧结点
  • 需要注意的是,所有顶点是按顶点序号顺序存储的

每一条弧也有一个结点:

tailheadheadlinktaillinkinfo

其中:

  • tail:弧尾顶点
  • head:弧头顶点
  • headlink:下一个弧尾相同的弧结点
  • taillink:下一个弧头相同的弧结点
  • info:弧的相关信息如权重等

存储结构定义如下:

#define MAX_VEX 100

class Graph{
public:
	// 弧结构
	typedef struct ArcNode{
		int tail;
		int head;
		ArcNode* headlink;
		ArcNode* taillink;
		// info
	}ArcNode;
	// 顶点结构
	typedef struct VexNode{
		// data
		ArcNode* firstout;
		ArcNode* firstin;
	};
private:
	VexNode vexList[MAX_VEX];
	int vexNum, arcNum;
public:
	// operations
};
3.2 Characteristic

十字链表的特点:

  • 既易找到顶点入边,也易找到顶点出边
  • 唯一确定一个图,但是图十字链表不唯一

4.邻接多重表

无向图的一种链式存储方式,解决邻接表法中难求顶点之间是否邻接的问题。同样,每条边也由一个结点表示:

markivexilinkjvexjlinkinfo

其中:

  • mark:标志域,标记是否被搜索过
  • ivex:对应表头的顶点
  • ilink:指向表头的顶点相关的下一条弧
  • jvex:表头顶点的邻接顶点,即这条弧的另外一个顶点
  • jlink:指向和这个邻接顶点相关的下一条弧

每个顶点也由一个结点表示:

datafirstedge

存储结构定义如下:

#define MAX_VEX

class Graph{
public:
	// 边表结点
	typedef struct ArcNode{
		bool mark;
		int ivex;
		int jvex;
		ArcNode* ilink;
		ArcNode* jlink;
		// info
	}ArcNode;
	// 顶点表结点
	typedef struct VexNode{
		// data
		ArcNode* firstEdge;
	}VexNode;
private:
	VexNode vexList[MAX_VEX];
	int vexNum, arcNum;
public:
	// operations
};

Basic Operation

常见的操作如下:

  • Adjacent(v1, v2) - bool:判断两个顶点是否邻接
  • Neighbors(v) - VexNode[]:返回这个所给顶点的所有邻接顶点
  • InsertVertex(data) - void:插入一个顶点
  • DeleteVertex(v) - void:删除一个顶点
  • AddEdge(v1, v2, info) - void:加入一条边
  • RemoveEdge(v1, v2) - void:移除一条边
  • … \dots

根据存储结构的不同,操作的定义也不同

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值