欧拉回路和欧拉路径

目录

欧拉回路基础

欧拉回路的定义

欧拉回路的性质

判断图中是否存在欧拉回路的java代码实现

寻找欧拉回路的三个算法

Hierholzer算法

详细思路

代码实现

欧拉路径

欧拉路径的定义

欧拉路径的性质


欧拉回路基础

欧拉回路的定义

欧拉回路遍历了所有的边,也就意味着遍历了所有的点,但这并不能代表有欧拉回路的地方都有哈密尔顿回路的,如下图的例子。

欧拉回路的性质

 上图四个点的度数都是奇数,所以不存在欧拉回路。

欧拉回路的条件:图是联通的、每个点的度数都是偶数。 

判断图中是否存在欧拉回路的java代码实现

public class EulerLoop {private Graph G;public EulerLoop(Graph G){this.G = G;}public boolean hasEulerLoop(){//判断图的连通性//这里的CC类是判断图的连通分量的个数// 在我CSDN文章的图的深度优先遍历的六种应用附Java代码文章的第一个例子中有Java代码CC cc = new CC(G);if(cc.count() > 1) return false;if(G.degree(v) % 2 == 1) return false;return true;}
}

寻找欧拉回路的三个算法

 前两个算法复杂度都比Hierholzer高得多,所以如果有参加竞赛的朋友要优先使用Hierholzer算法,尤其不要使用回溯法,几乎一定会超时。

Hierholzer算法

详细思路

Hierholzer算法使用两个栈,每走过一个顶点就把这个顶点压入curPath的栈中,每走过一条边就把这条边在图中删除,如下图的虚线表示。

我们先模拟走过的路径是A->B->C->A,最后回到A后发现无路可走了,我们就倒着把A、C出栈压入loop栈中,直到找到一个有其他路径可走的顶点,即B顶点。从B顶点出发还可以找到一个环,这个环和我们刚才删除的虚线环的公共顶点就是B顶点。

 我们继续从B顶点开始走,然后走过了这个新的环。

接下来我们继续回头看,把curPath的数挨个检查是否还有哪个顶点有其他路径可走,若没有则压入loop栈中。

现在curPath这个栈空了,就代表我们把这个图遍历完了,现在loop栈中存储的顶点顺序就是倒序的欧拉回路的顺序,即A->B->D->E->B->C->A。我们把loop栈中的顶点依次出栈就得到了一种欧拉回路。

其实我们也可以把loop栈设置成一个ArrayList数组,因为正着看其实就是欧拉回路的另一种顺序,我们正着看反着看也没什么区别。以上就是整个Hierholzer算法的思路。这是一个线性级别的算法,只和图中有几条边有关系。

代码实现

我们在实现代码过程中要不断地删除走过的边,所以我们要在自己的Graph类中添加removeEdge()方法。 首先对传入的v、w进行合理性判断,然后因为是无向图,所以要各自删除掉v、w相邻顶点中的它们。

 

//我们选择使用的是最经典的非递归实现
//Hierholzer算法还存在递归实现,感兴趣的朋友可以试着去写一下
import java.util.ArrayList;
public class EulerLoop {private Graph G;public EulerLoop(Graph G){this.G = G;}public boolean hasEulerLoop(){//判断图的连通性//这里的CC类是判断图的连通分量的个数// 在我CSDN文章的图的深度优先遍历的六种应用附Java代码文章的第一个例子中有Java代码CC cc = new CC(G);if(cc.count() > 1) return false;if(G.degree(v) % 2 == 1) return false;return true;}public ArrayList<Integer>result(){ArrayList<Integer> res = new ArrayList<>();if(!hasEulerLoop()) return res;Graph g = (Graph) G.clone();int curv = 0;stack.push(curv);while(!stack.empty()){if(g.degree(curv) != 0){stack.push(curv);int w = g.adj(curv).iterator().next();//第一个元素g.removeEdge(curv, w);curv = w;}else{res.add(curv);curv = stack.pop();}}return res;}
}

欧拉路径

欧拉路径的定义

欧拉路径的性质

欧拉路径的起始点不能随便选了,只能选取度数是奇数的点。感兴趣的朋友可以自己试着实现欧拉路径的代码实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/174019.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python基础入门----如何使用 Pipenv 在项目目录中创建虚拟环境

文章目录 引言Pipenv 简介安装 Pipenv在项目目录中创建虚拟环境1. 进入你的项目目录2. 设置环境变量3. 创建虚拟环境4. 激活虚拟环境结论引言 在Python开发中,使用虚拟环境是一种良好的实践,它可以帮助开发者管理项目的依赖,并避免不同项目间的依赖冲突。Pipenv 是一个流行…

[文件读取]shopxo 文件读取(CNVD-2021-15822)

1.1漏洞描述 漏洞编号CNVD-2021-15822漏洞类型文件读取漏洞等级⭐⭐漏洞环境VULFOCUS攻击方式 描述: ShopXO是一套开源的企业级开源电子商务系统。 ShopXO存在任意文件读取漏洞&#xff0c;攻击者可利用该漏洞获取敏感信息。 1.2漏洞等级 高危 1.3影响版本 ShopXO 1.4漏洞复现…

动态表单获取某一项值

<template><div><el-form :model"form" :rules"rules" ref"form"><el-row v-for"(item,index) in form.list" :key"index"><el-col :span"6"><el-form-item label"用户名称…

Maven依赖管理项目构建工具的安装与配置

本篇来自尚硅谷的笔记&#xff0c;在线视频观看&#xff1a;Maven依赖管理项目构建工具&#xff0c;更多笔记欢迎访问&#xff1a;小熊学Java 一、Maven简介 1、为什么学习Maven 1.1、Maven是一个依赖管理工具 ①jar 包的规模 随着我们使用越来越多的框架&#xff0c;或者框…

Postman模拟上传文件

如图&#xff0c;在F12抓到的上传文件的请求 那要在postman上模拟这种上传&#xff0c;怎么操作呢&#xff0c;如图&#xff0c;选中【Select File】选取文件上传即可

C++:OJ练习(每日练习!)

编程题&#xff1a; 题一&#xff1a;计算日期到天数的转换 计算日期到天数转换_牛客题霸_牛客网 (nowcoder.com) 示例1 输入&#xff1a; 2012 12 31 输出&#xff1a; 366 思路一&#xff1a; 第一步&#xff1a;创建年&#xff0c;月&#xff0c;日的变量&#xff0c;并按…

排序算法之-快速

算法原理 丛待排序的数列中选择一个基准值&#xff0c;通过遍历数列&#xff0c;将数列分成两个子数列&#xff1a;小于基准值数列、大于基准值数列&#xff0c;准确来说还有个子数列&#xff1a;等于基准值即&#xff1a; 算法图解 选出基准元素pivot&#xff08;可以选择…

应届裁员,天胡开局——谈谈我的前端一年经历

应届裁员&#xff0c;天胡开局——谈谈我的前端一年经历 许久没有更新了&#xff0c;最近一个月都在忙&#xff0c;没错&#xff0c;正如题目所说&#xff0c;裁员然后找工作… 这周刚重新上班&#xff0c;工作第二天&#xff0c;感慨良多&#xff0c;记录些什么吧。 去年十…

双向带头循环链表

今天我们在来学一个链表的内容&#xff0c;就是我们的双向带头循环链表&#xff0c;听名字就是一个很牛的链表&#xff0c;那我们今天就来把它的每个接口一个一个来实现。首先我们来看一下它的物理结构是一个什么样子的。 我们通过这个图可以很清楚的看到我们的前一个节点都是指…

记一次线上问题引发的对 Mysql 锁机制分析

背景 最近双十一开门红期间组内出现了一次因 Mysql 死锁导致的线上问题&#xff0c;当时从监控可以看到数据库活跃连接数飙升&#xff0c;导致应用层数据库连接池被打满&#xff0c;后续所有请求都因获取不到连接而失败 整体业务代码精简逻辑如下&#xff1a; Transaction p…

机器学习线性代数知识补充

线性代数知识补充 正交矩阵与正交变换方阵特征值与特征向量相似矩阵对角化二次型正定二次型 正交矩阵与正交变换 方阵特征值与特征向量 相似矩阵 对角化 二次型 正定二次型

【C++】类与对象 I

类与对象 I &#xff1a; 前言&#xff1a;&#xff08;C&#xff09;面向过程 和&#xff08;C&#xff09;面向对象 初步认识前言&#xff1a;类的引入一、类的介绍二、类的定义&#xff08;一&#xff09;class 语法&#xff08;二&#xff09;类的两种定义方式&#xff1a;…