一、邻接矩阵
- 一个图的邻接矩阵表示是唯一的。
- 适合于稠密图的存储。
- 邻接矩阵的存储空间为O(n^2)
- 邻接矩阵是图的顺序存储结构
- 顶点数组 —— 用一维数组存储顶点(元素)
- 邻接矩阵 —— 用二维数组存储顶点(元素)之间的关系(边或弧)
实现
顶点类型:
typedef struct
{
int no; // 顶点编号
char info; // 顶点的其他信息
}VertexType; // 顶点类型
图的邻接矩阵类型:
typedef struct
{
int edges[maxSize][maxSize]; // 边
int n,e; // 顶点数、边数
VertexType vex[maxSize]; // 存放结点信息
}MGraph; // 图的邻接矩阵类型
(1)无向图
表示顶点 i 与顶点 j 邻接,即 i 与 j 之间存在边或弧
表示顶点 i 与顶点 j 不邻接
(2)有向图
表示顶点 i 与顶点 j 邻接,即 i 与 j 之间存在边或弧
表示顶点 i 与顶点 j 不邻接,其中 i≠j
表示对角线的顶点,其中 i=j
二、邻接表
- 邻接表表示不唯一
- 适合于稀疏图存储。
- 邻接表的存储空间为0(n+e)
- 邻接表是链式存储结构
实现
边结点(表结点):
// 边结点
typedef struct
{
int info; // 该边的相关信息,如权值
ArcNode *nextarc; // 指向下一条边的指针
int adjvex; // 该边所指向结点的位置
}ArcNode;
头结点:
// 头结点
typedef struct
{
char data; // 顶点信息
ArcNode *firstarc; // 指向第一条边的指针
}VNode;
邻接表(用于存储头结点):
// 邻接表(用于存储头结点)
typedef struct
{
VNode adjlist[maxSize]; // 邻接表
int n,e; // 顶点数和边数(度)
}AGraph;
(1)无向图
(2)有向图
(3)有向网(带权图)
三、逆邻接表
四、十字链表(有向图)
若有向图 G 有 n 个顶点 e 条弧,则需 n 个表头结点和 e 个表结点。
有向图 G 的十字链表,单链表的长度 = 入度+出度。
求顶点 vi 的出度和入度都只需遍历 vi 对应的单链表,统计结点值为 i 的结点数。
实现
边结点(表结点)
typedef struct ArcBox{
int tailvex,headvex;/该弧的尾和头顶点的位置
struct ArcBox*hlink,*tlink;//分别为弧头(尾邻接表)相同和弧尾(邻接表)相同的弧的链域
}ArcBox;
头结点
typedef struct VexNode{
VertexType data;
ArcBox*firstin,*firstout;//分别指向该顶点的第一条入弧和出弧
}VexNode;
十字链表
typedef struct{
VexNode xlist[MAX_VERTEXT_NUM];//表头向量int vexnum,arcnum;/有向图的当前顶点数和弧数
}OLGraph;
五、邻接多重表(无向图)
实现
边结点(表结点)
typedef enum{unvisited,visited}visitedIf;typedef struct EBox{
visitedIf mark;//访问标记
intivex,jvex;/该边依附的两个顶点的位置
struct EBox*ilink,*jlink;//分别指向依附于这两个顶点的下一条边
}EBox;
头结点
typedef struct VexBox{
VertexType data;
EBox*firstedge;//指向第一条依附于该顶点边
}VexBox;
邻接多重表
typedef struct{
VexBox adjmullist[MAX_VERTEXT_NUM];
intvexnum,edgenum;//无向图的当前顶点数和边数
}AMLGraph;