图的存储结构
图的存储结构之邻接矩阵
邻接矩阵的定义
图的邻接矩阵(Adjacency Matrix) 存储方式是用两个数组来表示图。一个 一维数组存储图中顶点信息,一个 二维数组(称为邻接矩阵) 存储图中的边或弧的信息。
图的邻接矩阵实现思路
结点数为n的图G=(V)的邻接矩阵A是n x n的。
将G的顶点编号为V1,V2…Vn(数组下标)
若<Vi,Vj> ∈E,则 A [i][j] = 1,否则 A [i] [j] = 0
实例(有向图)
实例(无向图)
网的邻接矩阵实现思路
结点数为n的图G=(V)的邻接矩阵A是n x n的。
将G的顶点编号为V1,V2…Vn(数组下标)
若<Vi,Vj> ∈E,则 A [i] [j] = Wi,j,否则 A [i] [j] = ∞
实例(无向图)
参考代码实现
#define MaxVertexNum 100
typedef char VertexType;
typedef int EdgeType;
typedef struct{
VertexType Vex[MaxVertexNum]; //点集
EdgeType Edge[MaxVertexNum][MaxVertexNum]; //边集
int vexnum,arcnum; //结点数量,边的数量
}MGraph;
邻接矩阵的性质
1、邻接矩阵法的空间复杂为O(n2), 适用于 稠密图;
2、无向图的邻接矩阵为 对称矩阵;
3、无向图中第 i 行 (第 i 列) 非0元素 (非正无穷) 的个数为第 i 个顶点的度;
4、有向图中第 i 行 (第 i 列) 非0元素 (非正无穷) 的个数为第 i 个顶点的出度(入度)。
问题探索
问题:设图G的邻接矩阵为A,矩阵运算 A的n次 的含义???
小提示: 以下 An 代表 A的n次,例如 A2 代表 A的2次。
分析:
A2 [2] [5]=1 * 1 + 0 * 0 + 1 * 1 + 0 * 0 + 0 * 0 = 2
A2 [2] [5] = 2 表示从顶点v2到顶点v5长度为2的路径有 2 条
A3 [2] [5] = 0 * 1 + 0 * 0 + 1 * 1 + 1 * 0 + 2 * 0 = 1
A2 [2] [3] = 1 表示从顶点v2到顶点v3长度为2的路径有 1 条
A3 [2] [5] = 1 表示从顶点v2到顶点v5长度为3的路径有 1 条
结论:
An [i] [j] = x 表示从顶点Vi到顶点Vj长度为n的路径有 x 条;
即:An [i] [j] 表示从顶点Vi到顶点Vj长度为n的路径条数。
图的存储结构之邻接表
邻接表
总体思路 :为每个顶点建立一个单链表存放与它相邻的边。
顶点表 :采用顺序存储,每个数组元素存放顶点的数据和边表的头指针;
边表 :采用链式存储,单链表中存放与一个顶点相邻的所有边,一个链表结点表示一条从该顶点到链表结点顶点的边。
实例(无向图)
实例(有向图)
提示: 下图把顶点当作弧尾建立的 邻接表 ,如果把顶点当作弧头建立,则称为 逆邻接表。
参考代码实现
#define MaxVertexNum 100
typedef struct ArcNode{ //边表结点
int adjvex; //顶点下标
struct ArcNode *next; //指向下一个边表结点的指针
//Inforype info; //权值
}ArcNode;
typedef struct VNode{ //顶点表结点
VertexType data; //顶点数据
ArcNode *first; //指向它的单链表的头指针
}VNode, AdjList[MaxVertexNum];
typedef struct{
AdjList vetices; //定义邻接表
int vexnum,arcnum; //顶点数,边数
}ALGraph;
邻接表的特点
邻接矩阵 VS 邻接表
图的存储结构之十字链表
十字链表
十字链表 是有向图的一种链式存储结构。
实例
参考代码实现
#define MaxVertexNum 100
typedef struct ArcNode{ //边表结点
int tailvex,headvex;
struct ArcNode *hlink, tlink;
//Inforype info;
}ArcNode;
typedef struct vNodet{ //顶点表结点
VertexType data;
ArcNode *firstin, *firstout;
]VNode;
typedef struct{ //十字链表
VNode xlist[MaxVertexNum];
int vexnum,arcnum;
}GLGraph;
十字链表的优点
十字链表的好处就是因为把 ** 邻接表** 和 逆邻接表 整合在了一起 , 这样既容易找到以Vi为尾的弧,也容易找到以Vj为头的弧,因而容易求得顶点的出度和入度。
十字链表除了结构复杂一点外,其实创建图算法的肘间复杂度是和邻接表相同的,因此,在有向图的应用中,十字链表也是非常好的数据结构模型。
图的存储结构之邻接多重表
邻接多重表
邻接多重表:无向图的一种存储结构。
实例
参考代码实现
#define MaxVertexNum 100
typedef struct ArcNode{ //边表结点
int ivex,jvex;
struct ArcNode *ilink, *jlink;
//Inforype info;
//bool mark;
}ArcNode;
typedef struct VNode{ //顶点结点
VertexType data;
ArcNode *firstedge;
}VNode;
typedef struct{ //邻接多重表
VNode adjmulist[MaxVertexNum];
int vexnum,arcnum;
}AMLGraph;