图的逻辑结构: 多对多
- 图没有顺序存储结构
- 可以接住二维数组来确定元素之间的关系
- 邻接矩阵
一、邻接矩阵
思路
- 建立一个顶点表,邻接矩阵用来描述顶点的关系
例子
无向图 的邻接矩阵
- 无向图的邻接矩阵是对称的
- 顶点i的度是第i行1的个数
完全的邻接矩阵当中,对角元素为0,其余为1.
有向图的邻接矩阵
- 行为出度边、列为入度边
- 可能不是对称的邻接矩阵
- 出度=第i行元素之和
- 入度=第i列的元素之和
网的邻接矩阵
邻接矩阵的建立
邻接矩阵过的存储表示: 用两个数组分别存储顶点表和邻接矩阵;
1. 基本的语言定义
#define MaxInt 3412324;//MaxSize of
#define MVNum 100 //最大的顶点
typedef char VerTexType;
typedef int ArcType; // wight is int
typedef struct{
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int curVexNum,arcNum ;//arcNum and current Vex;
}AMGraph;
2. 无向网的定义
- 输入总的顶点数和总边树
- 依次输入点的信息存储顶点表当中
- 初始化邻接矩阵,是每个权威最大值
3. 邻接矩阵小总结
无向网转换成无向图&有向图
邻接矩阵-有什么优点?
二、邻接表
1. 无向图邻接表表示法(链)
- 邻接表不唯一
- n个顶点,e条边的无向图
- n个头结点
- 2e个表结点
- O(n+2e)
- 适合用存储稀疏图
- vi的度是单链表当中表结点的总数
- 例如下图v1有度为2
2. 有向图的邻接表
- 只记录入度结点
小练习
3. 邻接表的算法建立
定义
#define MVNum 100
//边结点结构
typedef struct ArcNode{
int adjvex;//指向边所指顶点位置
struct ArcNode *ne tarc; //指向下一条边的指针
OtherInfo info; //如果有权
}ArcNode;
//头结点
typedef struct VNode{
VerTexType data; //记录顶点的信息
ArcNode *firstarc; //指向第一条依附该顶点的边的指针
}VNode, AdjList[MVNum];//表示邻接表的类型
typede struct{
AdjList vertices;
int vexnum,arcnum;//当前顶点数,和弧数
}ALGraph;
建立算法实现
Status CreateUDG(ALgraph &G){
//输入总顶点个数和边数
//输入各点、构造表头的结点表
//输入个顶点的data
//表头结点初始化
//输入各个边,构造邻接表
//一条边依附两个顶点
//生成一个边结点的空间*p1
//p1->j
//插入顶点的头部
//无向图插入两次头部
}
4. 邻接表的优缺点与邻接矩阵的关系
邻接表的特点
- 容易找到顶点的邻接结点
- 节约稀疏图的空间
- 只需要n个顶点+2E个结点
- 方便计算 ‘度’?
- 方便无向图
- 有向图不好计算
-
邻接矩阵与邻接矩阵关系
1. 联系
-
2. 区别
对于任意一个无向图
- 邻接矩阵是确定切唯一的(矩阵的行列与顶点编号有关)
- 邻接表不唯一(链表的次序与顶点编号无关)
- 空间复杂度
- 邻接矩阵O(n^2)
- 邻接表O(n+e)
邻接矩阵多用于稠密图,邻接表多用途稀疏图
三、邻接表的改造与优化(略过)
在邻接表当中,对于有向图,求结点的度比较困难: 十字链表
在邻接表当中,对于无向图,每条边,都需要存储存储两边,浪费空间: 多重链表
1. 十字链表
其主要用于存储有向图,十字链表就是将邻接表和逆邻接表结合在一起,解决有向图求度困难的问题。