图的存储结构——十字链表,邻接多重表和边集数组
1.十字链表
为避免大量移动元素,采用稀疏矩阵的链式存储法——十字链表。
它的好处是能灵活地插入因运算而产生的非零元素,删除因运算而产生的新的零元素,实现矩阵的各种运算。
定义顶点表
typedef struct OLNode
{
int row,col;
ElementType value;
struct OLNode *right,*down;//指向的下一个结点也是同样的结构
}OLNode;*OLink;
定义边表结构
typedef struct
{
OLink *row_head,*col_head;//头指针
int m,n,len;//行,列,非零元素个数
}CrossList;
十字链表的好处就是因为把邻接表和逆邻接表整合在了一起,这样既容易找到以Vi为尾的弧,也容易找到以Vi为头的弧,因而容易求顶点的出度和入度。
2.邻接多重表
如果我们在无向图的应用中,关注的重点是顶点的话,邻接表是不错的选择,但如果我们更关注的是边的操作,比如对已经访问过的边做标记,或者删除某一条边,邻接表就显得不那么方便了。
因此,我们也仿照十字链表的方式,对边表结构进行改造,重新定义的边表结构如下:
iVex headEdge jVex headEdge
其中iVex 和jVex 是与某条边依附的两个顶点在顶点表中的下标,iLink 指向依附iVex的下一条边,jLink 指向依附jVex的下一条边。
也就是说,边表存放的是一条边而不是一个顶点。
顶点集
typedef struct VexNode
{
//顶点信息
char data;
//指向顶点所连接的边节点链表
ArcNode* firstEdge;
}VexNode;
边集
typedef struct ArcNode
{
//分别表示该边节点所连接的两个顶点
int iVex, jVex;
//指向有着相同头 尾顶点的边节点
struct ArcNode* headEdge, *tailEdge;
}ArcNode;
3.边集数组
边集数组是由两个一维数组构成,一个是存储顶点的信息,另一个是存储边的信息,这个边数组每个数据元素由一条边的起点下标end和权weight组成。
顶点表结构:(用来存储顶点信息)
typedef struct VertexNode /*顶点表结点*/
{
VerterType data;/*数据域*/
}vexs[MAX];
以下是图的边集数组表示法
typedef struct VertexNode /*顶点表结点*/
{
VerterType data;/*数据域*/
}vexs[MAX];
/*边数组结构*/
typedef struct edges
{
int begin;/*存储起点的下标*/
int end;/*存储终点的下标*/
int weight;/*权值*/
}Edges[MAX];
/*图的边集数组存储结构*/
typedef struct graph
{
Edges edge; /*边表结点结构*/
vexs Node; /*顶点表结点结构*/
int numVertexes; /*图中当前的顶点数*/
int numEdges; /*图中当前的边数*/
}graph;