图的逻辑结构: 多对多
- 图没有顺序存储结构
- 可以接住二维数组来确定元素之间的关系
- 邻接矩阵

一、邻接矩阵
思路
- 建立一个顶点表,邻接矩阵用来描述顶点的关系

例子
无向图 的邻接矩阵
- 无向图的邻接矩阵是对称的
- 顶点i的度是第i行1的个数

完全的邻接矩阵当中,对角元素为0,其余为1.
有向图的邻接矩阵
- 行为出度边、列为入度边
- 可能不是对称的邻接矩阵
- 出度=第i行元素之和
- 入度=第i列的元素之和
网的邻接矩阵
邻接矩阵的建立
邻接矩阵过的存储表示: 用两个数组分别存储顶点表和邻接矩阵;
1. 基本的语言定义
#define MaxInt 3412324;//MaxSize of#define MVNum 100 //最大的顶点typedef char VerTexType;typedef int ArcType; // wight is inttypedef 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. 十字链表
其主要用于存储有向图,十字链表就是将邻接表和逆邻接表结合在一起,解决有向图求度困难的问题。


