有向无环图VS树:
前言:
- Big-man在看着 《终极算法》 的时候,突然一个很要好的朋友(是一名程序媛)抛出了一数据结构有关的问题: 有向无环图 VS 树。Big-man想着他们之间有什么差别了,虽然这样想着。但是Big-man还是想着需要去分析一下的。
有向无环图:
定义:
- Big-man首先得去把有向无环图的定义给出:
- 简单的定义: 一个无环的有向图;英文称为
Directed Acyclic Graph
,简称DAG图。
###特点:
-
DAG图的特点:
-
DAG图是一类较有向树更一般的特殊有向图。
-
如下图所示:
-
以上给出的结构图中从左到右依次是: 树->有向无环图->有向图;
-
检查一个有向图是否存在环要比无向图本身复杂。
-
对于无向图来说,若深度优先遍历过程中遇到回边(即指向已访问过的顶点的边),则必定存在环;而对于有向图来说,这条回边有可能是指向深度优先生成森林中另一棵生成树上顶点的弧。
-
但是,如果从有向图上某个顶点v 出发的遍历,在
dfs(v)
(即深度优先遍历/深度优先搜索)结束之前出现一条从顶点u 到顶点v 的回边,由于u 在生成树上是v 的子孙,则有向图必定存在包含顶点v 和u 的环。
-
这里可能存在询问什么是深度优先遍历/深度优先搜索(
Depth_First_Search
)? -
深度优先遍历/深度优先搜索(英文是
Depth_First_Search
——简称:DFS
)——这个在实际应用当中比较广泛;提到DFS
,不得不提到的是图的遍历,因为图的遍历方式当中之一就是深度优先遍历,还有就是广度优先遍历。 -
图的遍历:
-
图的遍历不像树的遍历那样, 图的遍历需要在遍历的过程当中把访问过的顶点打上标记(做个记录),这样做是为了避免重复地去访问被访问过的顶点,一般记录访问过的顶点会定义一个访问数组如:
visited[n]
,n
表示图中顶点的个数,初始值为0,访问后设置为1。 -
深度优先遍历:
- 遍历方式:
-
( 对于连通图)从图中某个顶点v出发,访问此顶点,然后从v的未被访问的邻接点出发深度优先遍历图,直到图中所有和v有路径相通的顶点都被访问到。
-
对于非连通图,只需要对它的连通分量分别进行深度优先遍历,即在先前一个顶点进行一次深度优先遍历后,若图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直到图中所有的顶点都被访问过为止。
-
DFS其实就是一个递归的过程,就像一棵树的前序遍历。
-
- 遍历方式:
- 有向无环图的描述含有公共子式的表达式的有效工具。例如下述表达式:
- (a+b) * (b * (c+d)+(c+d) * e) * ((c+d) * e );
- 以上的公式用数据结构图表示 :
-
a、二叉树:
-
b、有向无环图:
-
给出程序分析的结构图出来,相信大家都会觉得是比较一目了然的了,以上的公式
(a+b) * (b * (c+d)+(c+d) * e) * ((c+d) * e )
你如果仔细观察的话,可以发现一些相同的子表达式,比如说是(c+d)
和(c+d)*e
等,在二叉树中,它们是会重复出现的,因为需要每一步都进行遍历。 -
但是如果使用得到是有向无环图的话,则可以实现对相同子式的共享,从而节省储存空间。
-
-
有向无环图是描述一项工程或系统的进行过程的有效工具。除最简