欧拉通路、欧拉回路、欧拉图和半欧拉图以及 Hierholzer 算法

概念:欧拉通路(又称欧拉路径)、欧拉回路、欧拉图和半欧拉图

定义

  • 通过图中所有边恰好一次且行遍所有顶点的通路称为欧拉通路(又称欧拉路径)
  • 通过图中所有边恰好一次且行遍所有顶点的回路称为欧拉回路
  • 具有欧拉回路的图称为欧拉图(Eulerian graph)
  • 具有欧拉通路但不具有欧拉回路的图称为半欧拉图(semi-Eulerian graph)
  • 欧拉回路是欧拉路径,欧拉路径不一定是欧拉回路。

特征

1.在无向图中:
​​  无向图G为欧拉图,当且仅当 G为连通图所有顶点的度为偶数
​​  无向图G为半欧拉图,当且仅当 G为连通图除了两个顶点的度为奇数之外,其它所有顶点的度为偶数

2.在有向图中:
​​  有向图G为欧拉图,当且仅当 G为连通图所有顶点的入度等于出度
​​  有向图G为半欧拉图,当且仅当 G为连通图存在某一顶点的入度比出度大1,还存在另一个顶点的入度比出度小1,而其它所有顶点的入度等于出度

其中我们可以发现:对于有向图的半欧拉图,它的欧拉路径的起点的度是出度 = 入度+1,终点的度是入度 = 出度+1。

连通图类型欧拉路径的顶点特征欧拉回路的顶点特征
无向图度为奇数的顶点数为 0 或 2度为奇数的顶点数为 0
有向图特征起点的入度 - 出度 = -1,终点的入度 - 出度 = 1, 其余顶点的入度 = 出度每个顶点的入度 = 出度

Hierholzer 算法

​​  Hierholzer 算法证明了一点:当存在欧拉路径或欧拉回路时,从合理的起点一直执行 DFS 遍历,最后得到的路径一定是欧拉路径或欧拉回路。

Hierholzer 算法用于寻找欧拉路径或欧拉回路(该算法假定图有欧拉路径或欧拉回路,其流程如下:

  • 从起点出发,进行深度优先搜索(DFS)
  • 每次沿着某条边从某个顶点移动到另外一个顶点的时候,都将这条边标记为已走过
  • 如果遇到阻塞(即当前顶点没有后续邻边或该顶点的邻边都走过),则将当前顶点加入到栈中,并回溯到上一顶点查找其可移动到的顶点

Hierholzer 算法的重要性质——即它是如何找到欧拉路径或欧拉回路:

  1. 使用 Hierholzer 算法后,如果该图为欧拉图,则栈底的必定为起点。如果该图为半欧拉图,则栈底的是与起点不同的另外一个奇度数顶点。——实际上栈底存储的都是终点,只是欧拉回路的终点就是起点。

证明:(下面的度数都是指出度 + 入度,下面的当前顶点是指入栈时的顶点)
​​  当顶点入栈时,说明当前顶点没有相邻边
​​​​  考虑到从起点出发到当前结点的路径中,除了起点和当前顶点外,其他的顶点都失去了偶数度数。(比如A->B->C->B->D,可以看出,除了起点A和当前顶点D,其它的顶点B和C都是至少一次一进一出,入度和出度失去的个数合起来就是偶数度数,C失去了1个入度和出度,B失去了2个入度和出度)
​​​​  关键的是如果起点和当前顶点不同,那么两者都失去了奇数度数。如果起点和当前顶点相同,则起点失去了偶数度数。(途经一顶点时,那个顶点会失去偶数度数。停留在某顶点时,会失去奇数度数,而当前顶点此时的度数为0,所以当前顶点的初始度数为奇数度数
​​  如果图中包含欧拉回路,意味着所有顶点的初始度数都是偶数。而当前顶点的当前度数为0,表示当前顶点的初始度数必定是奇数,这与欧拉图的特征产生矛盾,因此假设不成立。所以对于欧拉图,当前顶点就是起点
​​​​  同样地,对于欧拉路径,当前顶点不可能是起点,否则起点的初始度数就是偶数。而欧拉路径中起点和终点的度数一定是奇数。因此,当前顶点不是起点,但是它的初始度数也是奇数,所以一定是欧拉路径的终点。

  1. 如果该图为欧拉图或半欧拉图,则栈中的自底到顶的第 N N N 个顶点就是欧拉回路或欧拉路径上的第 N N N 个顶点。

证明:( deg ⁡ \deg deg 表示度数)​​
  在此只证明栈中相邻顶点在图中也为相邻顶点。因为模拟 Hierholzer 算法过程,可知该算法实际上就是在模拟“一笔画”过程,并且沿着画完的轨迹,从终点开始逆序逐一添加顶点到栈中。
​​  下面主要以 n = 2 n = 2 n=2 的情况为例,后面的情况可以此类推。并且为了不用纠结于区分欧拉回路和欧拉路径,不妨以半欧拉图为例。
​​  假设图中存在相邻的两顶点 V 1 V 2 V_1V_2 V1V2,并且 DFS 的过程中,先访问 V 2 V_2 V2 随后访问了 V 1 V_1 V1,并且 V 1 V_1 V1 成为第一个入栈的顶点。由性质一可知, V 1 V_1 V1 就是欧拉路径上的终点(入度 - 出度 = 1 的顶点为终点)。
​​  根据 Hierholzer 算法可知,在遍历过程中,因为删除了途径的边,所以此时路径中途经的所有顶点(包括起点和终点 V 1 V_1 V1 )的度数都为偶数(0或非0偶数)。那么当然 deg ⁡ ( V 2 ) \deg( V_2) deg(V2) 也是偶数,接下来就分类讨论。

  • 如果 deg ⁡ ( V 2 ) = 0 \deg( V_2) = 0 deg(V2)=0 ,也就是说当前顶点 V 2 V_2 V2 成为第二个入栈的顶点,那么 n = 2 n = 2 n=2 的情况就证毕了。
  • 如果 deg ⁡ ( V 2 ) > 0 \deg( V_2) > 0 deg(V2)>0 (即不为 0 的偶数),那么考虑当前包含 V 2 V_2 V2 的子图 G G G ,显然 G G G 是一个欧拉图,那么当前以 V 2 V_2 V2 为起点继续实施 Hierholzer 算法遍历剩下的相邻边,根据性质一, V 2 V_2 V2 将会是 G G G 中第一个入栈的顶点。也就是, V 2 V_2 V2 是原图中第二个入栈的顶点。

​​  对于第二种情况我们来举例讨论下:
在这里插入图片描述
  假设 JFK 先前往 KUL,即 JFK->KUL,可以看出 deg ⁡ ( J F K ) > 0 \deg(JFK) > 0 deg(JFK)>0 且是偶数,此时我们考虑当前包含 J F K JFK JFK 的子图,很明显这是一个欧拉图,那么由其定义我们可以知道,该子图第一个入栈的一定是 J F K JFK JFK。所以 J F K JFK JFK 是原图中紧接着 K U L KUL KUL 入栈的第二个顶点。
​​  综上所述,以此类推, V n − 1 V_{n-1} Vn1 入栈前最后接触过的 V n V_n Vn 将会是第 n n n 个入栈的顶点,再结合直观理解, V n V_n Vn 就是路径上的第 n n n 个顶点。

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值