图的定义
数据之间的关系可能是多种的,逻辑结构上来讲,分几种:
- 线性结构
- 非线性结构 【包括三种: 集合结构,树形结构,图状结构】
线性结构
线性结构的几种表现方式,前面大部分都了解过了:
- 线性表 (List)
- 栈(特殊的线性表) 【先进后出】 (Stack)
- 队列(特殊的线性表)【先进先出】 (Queue)
- 字符串,数组,广义表【广义表是特殊的线性表,广义表的元素可以是子表,子表的元素也可以是子表;如果广义表的每个元素都是原子,它就变成了线性表】
非线性结构
非线性结构中的 树(click me) ,各个数据之间的关系是一对多。
那么图 与树的区别就是,各个数据之间的关系是多对多。 图又有无向图与有向图,无向图为各个数据之间的关系是没有方向的,有向图反之,数据间是有方向的概念的。
顺序存储(数组表示)
如果一定用数组的话,需要一个二维数组来表示数据与数据之间的关系。 【邻接矩阵】
数组(邻接矩阵)表示法
1,需要一个(顶点)表,记录各个顶点的信息
2,一个邻接矩阵 存储各个顶点之间的关系
假如图A = G(V, E),有 n
个顶点
- 顶点表为一个一纬数组
Vexs[n]
,表示每个顶点代表的数据 - 邻接矩阵是一个二维数组
Arcs[n][n]
,表示各个顶点之间的关系
图中各个顶点的关系存在方向的情况下,节点只能单向通信,图就变成了有向图,。
无向图的邻接矩阵
1,无向图的邻接矩阵是对称矩阵
2,顶点的度就是第i行(列)中1
的个数。
完全图的邻接矩阵,对角线为0,其余全部是1。
有向图的邻接矩阵
注意:有向图的第i
行中1的个数表示以Vi
为起点的弧(出度边);有向图的第i
列中1的个数表示以Vi
为终点的弧(入度边)
1,有向图的邻接矩阵可能不是对称矩阵
2,顶点的出度 就是第i
行非0元素的个数总和
3,顶点的入度 就是第i
列非0元素的个数总和
四字真言:行出列入
有向网的邻接矩阵
什么是有向网,就是有向图中,具有方向的两个顶点之间存在一个特殊意义的数据,比如权重值。将上面有向图的1改为存在特殊意义的权重值即可。
如果用javascript代码来表示应该是这样:
vexs 是一位数组,存放n个顶点,arcs 是一个二维数组,存放各个顶点之间的关系和数据
顶点为n个,那么arcs是n*n的二维数组
function Graph(vexs = [], arcs = []) {
this.vexs = vexs
this.arcs = arcs
}
邻接矩阵的优缺点
优点:
- 查找某一个顶点的出度与入度很方便
- 查找某两个顶点的权值也很方便
缺点:
- 不利于添加和删除点
- 空间复杂度为
n^2
,在存储稀疏图(顶点很多,但是边很少)的时候,会浪费大量存储空间 - 在统计图中有多少条边的情况下,需要遍历整个arcs数组,时间复杂度为
n^2
, 浪费时间
链式存储 (链式表示)
链式表表示法----【邻接表/ 邻接多重表 / 十字链表】
TO BE CONTINUED