组成
顶点 + 边
(边可以没有但是至少有一个顶点)
图Graph是顶点vertex集合和边(也称之为弧 edge)集合组成。
- G=(V,E) 这里V是vertex顶点集合,E是edge边集合
- E=(Vi,Vj) 表示顶点i和顶点j之间的连线(边,弧)
常用术语
- 无向边:2边都能通行,用圆括号表示(类似双链表)
- 有向边:反之,用尖括号表示,(也称之为弧)
- 权:可以表示一个距离,(带权重的图Graph叫做网NetWork)
- 度:无向图顶点的边数量叫做度(因为往返的重复,度 = 边数 * 2),有向图分为出度和入度
- 出度:顶点向外发出的边的数组
- 入度:通向(进入)顶点的变的数目,
- 网:带权重的图(请注意区分权重不是度,比如地图的距离就是边长的一种权重)
- 弧:有向边称之为弧
图的分类
- 有向图:有方向的图,比如 A → B A \to B A→B 单向通行
- 无向图:没有方向的图比如 A − B A - B A−B 双向通行
- 完全图:任意2点都有边向连接
- 稀疏图:相对而言边(弧)比较少的图
- 稠密图:相对而言边(弧)比较多的图
数据结构(重点)
如果我们要表示下面有向图结构由5种数据方法
1.邻接矩阵
- 用一个固定长度的一维数组表示顶点
vertexs[4]
,相同长度的二维数组edges[4][4]
表示有向边 - 例如A到B的距离是4,所以第一行(对应顶点A)的第二个元素
edges[0][1] = 4
数组的查询是很快,
但是当稀疏图(就是图中的边十分少)的时候,二维数组是比较浪费内存,并且增加边和删除边十分不便,因此我们引出我们的第二个数据结构,邻接表
2.邻接表
邻接表表示上面的图graph如下
- 顶点集合为数组,顶点数组节点vertexNode,数组节点中vertex 表示顶点 ,edges 表示 代表边节点edgeNode的链表,
- 边链表节点,edgeNode :adjVex 表示adjacency vertex 指向下一个定点的下标,(比如第一行的A顶点的第一个edgeNode 指向自己,第二个edgeNode 指向 下标为1 的B,第三个edgeNode 指向下标为 2 的 C)
- edgeNode 中 weight :代表权重,这里表示二个顶点之间的距离。
- edgeNode 中的 next 指向连接到其他节点的边
- 我这里讨论了自身节点的情况,如果业务没有这个需求 ,你完全可以不必考虑这个情况
数据结构 | 优点 | 缺点 |
---|---|---|
邻接矩阵 | 二维数组,实现简单,能同时求出顶点的出度和入度 | 稀疏图造成的空间浪费 |
邻接表 | 数组+链表,不会空间浪费 | 不能同时求出出度和入度;对边的操作需要2次 |
十字链表 | 横竖十字链表:可以同时求出出度和入度 | 对边的操作需要2次 |
邻接多重表 | 对边的操作减少到了一次 | 删除较为复杂 |
备注:这里的链表插入是遍历到链表尾部再插入,效率比较低下,建议使用“头插法”