浅谈数据结构与算法(五)

数据结构与算法(五)

    • 图的定义
    • 图的存储方式
    • 图的遍历
    • 图的最短路径

图是一种网状数据结构,是由非空的顶点集合和一个描述顶点之间关系的集合组成,它是多对多的关系。

图的定义

图的形式化定义如下:

  • 图是由(V, E)来表示的,对于无向图来说,其中 V = (v0, v1, … , vn),E = { (vi,vj) (0 <= i, j <= n且i 不等于j)},对于有向图,E = { < vi,vj > (0 <= i, j <= n且i 不等于j)}。
    V是具有相同特性的数据元素的集合,V中的数据元素通常被称为顶点。
    E是两个顶点之间的关系的集合,也就是边的集合

  • ∈E,表示从顶点vi到顶点vj的一条弧,并称vi为弧尾或起始点,vj称为弧头或终止点。此时图中的顶点之间的连线是有方向的,这样的图称为有向图

  • ∈E则必有∈E,则关系E是对称的,此时可以使用一个无序对(vi,vj)来代替两个无序对,它表示顶点vi和顶点vj之间的一条边,此时图中顶点之间的连线是没有方向的,这种图称为无向图

在无向图和有向图中V中的元素称为顶点,而顶点之间的关系称为,在不影响理解的情况下,我们接下来将它们称为

并且顶点和边的数量都是有限的,我们记为|V|和|E|。
浅谈数据结构与算法(五)_第1张图片
无向图其实也是有向图,它是双向图。
浅谈数据结构与算法(五)_第2张图片
加权图:

  • 在实际应用中,图不但需要表示元素之间是否存在某种关系
    而且图的边往往与具有实际意义的数字有关,即每条边都有与它相似的实数,称为
    这些权值可以表示从一个顶点到另一个顶点的距离或者时间等意义,在下文中的权值均为正数。

比如上图所示,每条边上面的数字既可以代表距离,也可以代表时间。具体代表什么要看当用它的时候代表的实际意义。

图的存储方式

但是在正常的生活中,当我们使用图的时候,图是如何存储的呢。

邻接矩阵:二位数组 -> 顺序存储结构
浅谈数据结构与算法(五)_第3张图片
浅谈数据结构与算法(五)_第4张图片

邻接表: 链表 -> 链式存储结构
浅谈数据结构与算法(五)_第5张图片
链式存储的方式从图中可以看出是使用了数组和链表的方式。

图的遍历

图的遍历就是从某个顶点出发,按照某种方法对图中的所有顶点访问且访问一次。
图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础。

  • 深度优先算法:类似于树的先序遍历,是树的先序遍历的推广。(可以采用递归和借助栈的非递归方式实现)
  • 广度优先算法:类似于树的层次遍历,它是树的层次遍历的推广(借助队列的非递归方式实现)

eg1:
浅谈数据结构与算法(五)_第6张图片
无向图的深度优先遍历:0->1->3->7->4->2->5->6
无向图的广度优先遍历:0->1->2->3->4->5->6->7

eg2:
浅谈数据结构与算法(五)_第7张图片
无向图的深度优先遍历:a b c e f d g h i
无向图的广度优先遍历:a b c d e f g h i
(答案并不是唯一的,前面讲过在实际应用场景,图的存储方式使用链式存储方式较多,所以在遍历的过程中要看你是如何存储数据的,再得出相应的遍历顺序)

图的最短路径

  • 最短路径的概念:在许多应用领域中,带权图都被用来描述某个网络,比如通信网络、交通网络等,这种情况下,各边的权重就对应两点之间的通信的成本或者交通费用或者距离,典型的问题就是在任意指定的两点之间如果存在通路,那么最小的消耗是多少。这类问题实际上就是求解两个顶点之间最小的路径是多少。

问题:计算v1->v8的距离是多少?
浅谈数据结构与算法(五)_第8张图片
解1:段数最少的最短路径
如:所经历的边或弧最少的路径(拿坐地铁来说就是换乘最少)
解决方法:广度优先搜索,和权值无关,需要借助队列来实现

对于已经检查的顶点标记为已检查,否则会出现无限循环,可以新创建一个列表用于存储已经检查的顶点,找到目标顶点则结束。第一次找到就是跳转最少的路径。如果最后队列为空,就说明没有路径可以到达目标顶点。

新建两个队列S T

  • 我们从顶点v1开始,S -> v1 T -> 空
  • v1的相邻顶点是v2,v3,v4,则v1出队,v2,v3,v4入队。S ->v2 v3 v4;T->v1(记作v1已经被访问过了,以此类推)
  • 接下来看v2相邻顶点是v3 v5 v6,则v2出队, v3 v5 v6入队。S-> v3 v4 v3 v5 v6; T -> v1 v2
  • 接下来看v3相邻顶点是v4 v6,则v3出队, v4 v6入队。 S->v4 v3 v5 v6 v4 v6; T-> v1 v2 v3
  • 接下来看v4相邻顶点是v6 v7,则v4出队, v6 v7入队。S->v3 v5 v6 v4 v6 v6 v7;T-> v1 v2 v3 v4
  • 接下来是v3,但是在T队列中它已经是被访问的了,所以直接出队。
  • 以此类推到最后v8,第一次找到v8则就是最短路径。如果到最后都出队,队列为空则表示没有路径可以到达目标顶点。

解2:权值最小的路径
eg:时间最少,距离最少
解决方法:狄克斯特拉算法

我们创建两个数组
数组S:v1
数组T:v2 v3 v4 v5 v6 v7 v8
创建一个表格(-1表示无穷)

前一个结点 当前结点 权值
v1 v2 -1(3)
v1 v3 -1(5)
v1 v4 -1(6)
v5 -1
v6 -1
v7 -1
v8 -1

表示的是从v1开始,它可以通向的结点是v2 v3 v4,并且权值分别是3 5 6。比无穷大要小,所以替换掉-1。

下一步把v2取出来
数组S:v1 v2
数组T:v3 v4 v5 v6 v7 v8

前一个结点 当前结点 权值
v1 v2 3
v2 v3 5 (1 + 3)
v1 v4 6
v2 v5 -1(7+3)
v2 v6 -1(4+3)
v7 -1
v8 -1

可以看出v2可以通向的结点是v3 v5 v6,权值分别是1 7 4。我们已知从v1 -> v3的权值是5,v1->v2的权值是3,v2->v3的权值是1,可以得出v1->v2->v3的权值是1 + 3 =4,小于从v1->v3的权值5。所以用1+3替换掉5.同理v5 v6的权值是7+3和4+3
得出新表

前一个结点 当前结点 权值
v1 v2 3
v2 v3 4
v1 v4 6
v2 v5 10
v2 v6 7
v7 -1
v8 -1

接下来看v3可以通向的结点是v4 v6,权值分别是1 2。
数组S:v1 v2 v3
数组T:v4 v5 v6 v7 v8

前一个结点 当前结点 权值
v1 v2 3
v2 v3 4
v3 v4 6(1 + 4)
v2 v5 10
v3 v6 7(2 + 4)
v7 -1
v8 -1

同理得出新表

前一个结点 当前结点 权值
v1 v2 3
v2 v3 4
v3 v4 5
v2 v5 10
v3 v6 6
v7 -1
v8 -1

接下来看V4
数组S:v1 v2 v3 v4
数组T:v5 v6 v7 v8
v4可以通向的结点有v6和v7,权值分别是3 5

前一个结点 当前结点 权值
v1 v2 3
v2 v3 4
v3 v4 5
v2 v5 10
v3(v4) v6 6(3+5)
v4 v7 -1(5)
v8 -1

可以看出,当v6的上一个结点是v4的时候,它的最小权值是8,当v6的上一个结点是v3的时候,它的最小权值是6,所以这里不做替换。得出新表

前一个结点 当前结点 权值
v1 v2 3
v2 v3 4
v3 v4 5
v2 v5 10
v3 v6 6
v4 v7 5
v8 -1

以此类推到最后的结果是:

前一个结点 当前结点 权值
v1 v2 3
v2 v3 4
v3 v4 5
v6 v5 8
v3 v6 6
v6 v7 7
v7 v8 12

最后可以得出从v1到v8的最小权值的路线是
v1->v2->v3->v6->v7->v8,权值为12。

图的应用在实际开发中,用的很少。但是它用到的数据结构和hashMap等数据结构有些相似的地方,用作了解吧。

本博客文章皆出于学习目的,个人总结或摘抄整理自网络。引用参考部分在文章中都有原文链接,如疏忽未给出请联系本人。另外,如文章内容有错误,欢迎各方大神指导交流。

你可能感兴趣的:(数据结构与算法)