当前位置: 首页 > news >正文

图论11-欧拉回路与欧拉路径+Hierholzer算法实现

文章目录

  • 1 欧拉回路的概念
  • 2 欧拉回路的算法实现
  • 3 Hierholzer算法详解
  • 4 Hierholzer算法实现
    • 4.1 修改Graph,增加API
    • 4.2 Graph.java
    • 4.3 联通分量类
    • 4.4 欧拉回路类

1 欧拉回路的概念

在这里插入图片描述

在这里插入图片描述

2 欧拉回路的算法实现

private boolean hasEulerLoop(){CC cc = new CC(G);if(cc.count() > 1) return false;for(int v = 0; v < G.V(); v ++)if(G.degree(v) % 2 == 1) return false;return true;
}

3 Hierholzer算法详解

在这里插入图片描述

public ArrayList<Integer> result(){ArrayList<Integer> res = new ArrayList<>();if(!hasEulerLoop()) return res;//根据小g进行删边Graph g = (Graph)G.clone();Stack<Integer> stack = new Stack<>();int curv = 0; //出发点stack.push(curv);while(!stack.isEmpty()){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;
}

4 Hierholzer算法实现

4.1 修改Graph,增加API

//移除边
public void removeEdge(int v, int w){validateVertex(v);validateVertex(w);if(adj[v].contains(w)) E --;adj[v].remove(w);adj[w].remove(v);
}//深拷贝
@Override
public Object clone(){try{Graph cloned = (Graph) super.clone();cloned.adj = new TreeSet[V];for(int v = 0; v < V; v ++){cloned.adj[v] = new TreeSet<Integer>();for(int w: adj[v])cloned.adj[v].add(w);}return cloned;}catch (CloneNotSupportedException e){e.printStackTrace();}return null;
}

4.2 Graph.java

package Chapter08_EulerLoop_And_EulerPath;import java.io.File;
import java.io.IOException;
import java.util.TreeSet;
import java.util.Scanner;/// 暂时只支持无向无权图
public class Graph implements Cloneable{private int V;private int E;private TreeSet<Integer>[] adj;public Graph(String filename){File file = new File(filename);try(Scanner scanner = new Scanner(file)){V = scanner.nextInt();if(V < 0) throw new IllegalArgumentException("V must be non-negative");adj = new TreeSet[V];for(int i = 0; i < V; i ++)adj[i] = new TreeSet<Integer>();E = scanner.nextInt();if(E < 0) throw new IllegalArgumentException("E must be non-negative");for(int i = 0; i < E; i ++){int a = scanner.nextInt();validateVertex(a);int b = scanner.nextInt();validateVertex(b);if(a == b) throw new IllegalArgumentException("Self Loop is Detected!");if(adj[a].contains(b)) throw new IllegalArgumentException("Parallel Edges are Detected!");adj[a].add(b);adj[b].add(a);}}catch(IOException e){e.printStackTrace();}}public void validateVertex(int v){if(v < 0 || v >= V)throw new IllegalArgumentException("vertex " + v + "is invalid");}public int V(){return V;}public int E(){return E;}public boolean hasEdge(int v, int w){validateVertex(v);validateVertex(w);return adj[v].contains(w);}public Iterable<Integer> adj(int v){validateVertex(v);return adj[v];}public int degree(int v){validateVertex(v);return adj[v].size();}public void removeEdge(int v, int w){validateVertex(v);validateVertex(w);if(adj[v].contains(w)) E --;adj[v].remove(w);adj[w].remove(v);}@Overridepublic Object clone(){try{Graph cloned = (Graph) super.clone();cloned.adj = new TreeSet[V];for(int v = 0; v < V; v ++){cloned.adj[v] = new TreeSet<Integer>();for(int w: adj[v])cloned.adj[v].add(w);}return cloned;}catch (CloneNotSupportedException e){e.printStackTrace();}return null;}@Overridepublic String toString(){StringBuilder sb = new StringBuilder();sb.append(String.format("V = %d, E = %d\n", V, E));for(int v = 0; v < V; v ++){sb.append(String.format("%d : ", v));for(int w : adj[v])sb.append(String.format("%d ", w));sb.append('\n');}return sb.toString();}public static void main(String[] args){Graph g = new Graph("g.txt");System.out.print(g);}
}

4.3 联通分量类

package Chapter08_EulerLoop_And_EulerPath;import java.util.ArrayList;public class CC {private Graph G;private int[] visited;private int cccount = 0;public CC(Graph G){this.G = G;visited = new int[G.V()];for(int i = 0; i < visited.length; i ++)visited[i] = -1;for(int v = 0; v < G.V(); v ++)if(visited[v] == -1){dfs(v, cccount);cccount ++;}}private void dfs(int v, int ccid){visited[v] = ccid;for(int w: G.adj(v))if(visited[w] == -1)dfs(w, ccid);}public int count(){return cccount;}public boolean isConnected(int v, int w){G.validateVertex(v);G.validateVertex(w);return visited[v] == visited[w];}public ArrayList<Integer>[] components(){ArrayList<Integer>[] res = new ArrayList[cccount];for(int i = 0; i < cccount; i ++)res[i] = new ArrayList<Integer>();for(int v = 0; v < G.V(); v ++)res[visited[v]].add(v);return res;}public static void main(String[] args){Graph g = new Graph("g.txt");CC cc = new CC(g);System.out.println(cc.count());System.out.println(cc.isConnected(0, 6));System.out.println(cc.isConnected(5, 6));ArrayList<Integer>[] comp = cc.components();for(int ccid = 0; ccid < comp.length; ccid ++){System.out.print(ccid + " : ");for(int w: comp[ccid])System.out.print(w + " ");System.out.println();}}
}

4.4 欧拉回路类

package Chapter08_EulerLoop_And_EulerPath;import java.util.ArrayList;
import java.util.Stack;public class EulerLoop {private Graph G;public EulerLoop(Graph G){this.G = G;}private boolean hasEulerLoop(){CC cc = new CC(G);if(cc.count() > 1) return false;for(int v = 0; v < G.V(); v ++)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();Stack<Integer> stack = new Stack<>();int curv = 0;stack.push(curv);while(!stack.isEmpty()){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;}public static void main(String[] args){Graph g = new Graph("g8.txt");EulerLoop el = new EulerLoop(g);System.out.println(el.result());Graph g2 = new Graph("g2.txt");EulerLoop el2 = new EulerLoop(g2);System.out.println(el2.result());}
}

在这里插入图片描述

相关文章:

图论11-欧拉回路与欧拉路径+Hierholzer算法实现

文章目录 1 欧拉回路的概念2 欧拉回路的算法实现3 Hierholzer算法详解4 Hierholzer算法实现4.1 修改Graph&#xff0c;增加API4.2 Graph.java4.3 联通分量类4.4 欧拉回路类 1 欧拉回路的概念 2 欧拉回路的算法实现 private boolean hasEulerLoop(){CC cc new CC(G);if(cc.cou…...

(一)什么是Vite——vite介绍与使用

什么是Vite Vite&#xff08;法语意为 "快速的"&#xff0c;发音 /vit/&#xff0c;发音同 "veet"&#xff09;是一种新型前端构建工具&#xff0c;能够显著提升前端开发体验。 它主要由两部分组成&#xff1a; 一个开发服务器&#xff0c;它基于 原生 …...

直流电动机四象限运行控制变流器设计

摘 要 节能和效率是工业经济发展的主题&#xff0c;电机在各行各业都是主要的动力来源&#xff0c; 直流电机以其控制简单&#xff0c;效率高&#xff0c;功率密度大等优势脱颖而出。基于直流电动机四象限运行控制变流器应用广泛&#xff0c;比如电子设备、电机控制、工业等行…...

虹科示波器 | 汽车免拆检修 | 2021款广汽丰田威兰达PHEV车发动机故障灯异常点亮

一、故障现象 一辆2021款广汽丰田威兰达PHEV车&#xff0c;搭载A25D-FXS发动机和动力蓄电池系统&#xff08;额定电压为355.2V&#xff0c;额定容量为45.0Ah&#xff09;&#xff0c;累计行驶里程约为1万km。车主反映&#xff0c;高速行驶时发动机突然抖动&#xff0c;且发动机…...

机器学习和深度学习领域的算法和模型

机器学习和深度学习领域有许多算法和模型&#xff0c;以下是一些常见的算法和模型&#xff1a; 线性回归&#xff08;Linear Regression&#xff09;逻辑回归&#xff08;Logistic Regression&#xff09;决策树&#xff08;Decision Tree&#xff09;随机森林&#xff08;Ran…...

减轻关键基础设施网络安全风险的 3 种方法

物理安全和网络安全之间存在相当大的重叠&#xff0c;特别是在保护关键基础设施方面。防止基础设施被篡改需要在物理安全方面进行大量投资&#xff0c;但任何连接到互联网的设备都代表着更广泛网络的潜在攻击点。 缺乏足够保护的设备可能会给这些对手在网络中提供立足点&#…...

Redis的特性以及使用场景

分布式发展历程参考 陈佬 http://t.csdnimg.cn/yYtWK 介绍redis Redis&#xff08;Remote Dictionary Server&#xff09;是一个基于客户端-服务器架构的在内存中存储数据的中间件&#xff0c;属于NoSQL的一种。它可以用作数据库、缓存/会话存储以及消息队列。 作为一种内存数…...

【python后端】- 初识Django框架

Django入门 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff0c;大家一起学习成长&#xff01; 文章目录 Django入门…...

队列与堆栈:原理、区别、算法效率和应用场景的探究

队列与堆栈&#xff1a;原理、区别、算法效率和应用场景的探究 前言原理与应用场景队列原理应用场景&#xff1a; 堆栈原理应用场景递归原理和堆栈在其中的作用递归原理堆栈作用 队列与堆栈区别队列堆栈算法效率 前言 本文主要讲解数据结构中队列和堆栈的原理、区别以及相关的…...

数据结构与算法【链表:一】Java实现

目录 链表 单向链表 哨兵链表 双向链表 环形链表 链表 链表是数据元素的线性集合&#xff0c;其每个元素都指向下一个元素&#xff0c;元素存储上并不连续。 随机访问性能 根据 index 查找&#xff0c;时间复杂度 O(n) 插入或删除性能 起始位置&#xff1a;O(1)结束位…...

数据结构 | 队列的实现

数据结构 | 队列的实现 文章目录 数据结构 | 队列的实现队列的概念及结构队列的实现队列的实现头文件&#xff0c;需要实现的接口 Queue.h初始化队列队尾入队列【重点】队头出队列【重点】获取队列头部元素获取队列队尾元素获取队列中有效元素个数检测队列是否为空销毁队列 Que…...

flutter 集成 高德地图,退出界面闪退

android:allowNativeHeapPointerTagging"false"应用尝试释放系统堆分配器未分配的指针。 应用中的某个部分修改了指针的顶部字节。不能修改指针的顶部字节&#xff0c;您需要更改代码来修复此问题。 指针的顶部字节被错误使用或修改的示例包括&#xff1a; 指向特定…...

数据结构----链式栈的操作

链式栈的定义其实和链表的定义是一样的&#xff0c;只不过在进行链式栈的操作时要遵循栈的规则----即“先进后出”。 1.链式栈的定义 typedef struct StackNode {SElemType data;struct StackNode *next; }StackNode,*LinkStack; 2.链式栈的初始化 Status InitStack(LinkSta…...

识别伪装IP的网络攻击方法

识别伪装IP的网络攻击可以通过以下几种方法&#xff1a; 观察IP地址的异常现象。攻击者在使用伪装IP地址进行攻击时&#xff0c;往往会存在一些异常现象&#xff0c;如突然出现的未知IP地址、异常的流量等。这些现象可能是攻击的痕迹&#xff0c;需要对此加以留意。 检查网络通…...

C 语言指针

C 语言指针 在本教程中&#xff0c;您将学习指针。什么是指针&#xff0c;如何使用它们以及在示例的帮助下使用它们时可能遇到的常见错误。 指针是 C和C 编程的强大功能。在学习指针之前&#xff0c;让我们学习一下C语言编程中的地址。 C 语言地址 如果程序中有变量var&am…...

学【Java多态】-- 写高质量代码

多态的实现条件 在java中要实现&#xff0c;必须要满足如下几个条件&#xff0c;缺一不可。 1.必须在继承体系下2.子类必须要对父类中的方法进行重写3.通过父类的引用调用冲写的方法。 想要真正的学好多态需要去学习一些前置知识&#xff0c;那我们直接开始吧&#xff01; …...

【汇编】内存的读写与地址空间、寄存器及数据存储

文章目录 前言一、CPU对存储器的读写1.1 cpu对存储器的读写如何进行&#xff1f;1.2 演示 二、内存地址空间三、将各类存储器看作一个逻辑存储器——统一编址内存地址空间的分配方案 三、CPU的组成寄存器是CPU内部的信息存储单元通用寄存器--AX为例“横看成岭侧成峰“ 四、“字…...

DSP生成hex方法

以下使用两种方法生成的HEX文件&#xff0c;亲测可用 &#xff08;1&#xff09;万能法 不管.out文件是哪个版本CCS编译器生成的&#xff0c;只要用HEX2000.exe软件&#xff0c;翻译都可以使用。方法&#xff1a; hex2000 -romwidth 16 -memwidth 16 -i -o 20170817chuankou…...

GZ038 物联网应用开发赛题第7套

2023年全国职业院校技能大赛 高职组 物联网应用开发 任 务 书 &#xff08;第7套卷&#xff09; 工位号&#xff1a;______________ 第一部分 竞赛须知 一、竞赛要求 1、正确使用工具&#xff0c;操作安全规范&#xff1b; 2、竞赛过程中如有异议&#xff0c;可向现场考评…...

ELK之Logstash解析时间相差8h的问题

一、问题描述 服务器当前时间为&#xff1a;2022年 06月 28日 星期二 11:24:22 CST 而logstash解析的时间为2022-06-28T03:15:25.545Z与实际时间相差8h 一、解决办法&#xff1a; 需改logstash的配置文件&#xff1a; 原理就是&#xff1a;定义一个中间变量timestamp&…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG

TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码&#xff1a;HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...