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

0107连通分量-无向图-数据结构和算法(Java)

文章目录

    • 1 API
    • 2 代码实现和分析
    • 测试
    • 后记

1 API

深度优先搜索下一个直接应用就是找出一幅图中的连通分量,定义如下API。

public class CC
CC(Graph g)预处理构造函数
booleanconnected(int v, int w)v和w连通吗
intcount()连通分量数
intid(int v)v所在的连通分量标识符(0~count()-1)

2 代码实现和分析

package com.gaogzhen.datastructure.graph.undirected;import com.gaogzhen.datastructure.stack.Stack;
import edu.princeton.cs.algs4.Graph;
import edu.princeton.cs.algs4.Queue;import java.util.*;/*** 无向图连通分量* @author: Administrator* @createTime: 2023/03/08 20:18*/
public class CC {/*** 顶点是否标记数组*/private boolean[] marked;/*** 顶点所在连通分量标志:0~count()-1*/private int[] id;/*** 每个连通分量顶点数量*/private int[] size;/*** 连通分量数量*/private int count;/*** 要处理的无向图*/private Graph graph;/*** 计算给定无向图的连通分量* @param graph 指定的无向图*/public CC(Graph graph) {this.graph = graph;int len = graph.V();// 初始化marked = new boolean[len];id = new int[len];size = new int[len];// 搜索连通分量bfs();}/*** 深度优先搜索连通分量*/private void dfs() {// 深度优先非递归实现,借助栈Stack<Iterator<Integer>> c = new Stack<>();// 搜索连通分量for (int v = 0; v < graph.V(); v++) {// 遍历图中所有顶点,以没有被标记过的顶点为起点,搜索连通分量// 执行完一次bsf,标记一个包含顶点v的连通分量if (!marked[v]) {dfs(c, v);// 连通分量标记+1count++;}}}/*** 深度优先搜索连通分量* @param v 起点*/private void dfs(Stack<Iterator<Integer>> c, int v) {if (!marked[v]) {// 起点未标记,标记计数加1// 起点默认没标记,可以不加是否标记判断marked[v] = true;id[v] = count;size[count]++;Iterable<Integer> iterable = graph.adj(v);Iterator<Integer> it;if (iterable != null && (it = iterable.iterator()) != null){// 顶点对应的邻接表迭代器存入栈c.push(it);}}while (!c.isEmpty()) {Iterator<Integer> it = c.pop();int x;while (it.hasNext()) {// 邻接表迭代器有元素,获取元素x = it.next();if (!marked[x]) {// 顶点未被标记,标记计数+1marked[x] = true;id[x] = count;size[count]++;if (it.hasNext()) {// 邻接表迭代器有元素重新入栈c.push(it);}// 深度优先原则,当前迭代器入栈,新标记顶点的邻接表迭代器入栈,下次循环优先访问Iterable<Integer> iterable = graph.adj(x);if (iterable != null && (it = iterable.iterator()) != null){c.push(it);}break;}}}}/*** 广度优先搜索连通分量*/private void bfs() {// 广度优先非递归实现,借助队列Queue<Integer> q = new Queue<>();// 搜索连通分量for (int v = 0; v < graph.V(); v++) {// 遍历图中所有顶点,以没有被标记过的顶点为起点,搜索连通分量// 执行完一次bsf,标记一个包含顶点v的连通分量if (!marked[v]) {bfs(q, v);// 连通分量标记+1count++;}}}private void bfs(Queue<Integer> q, int v) {marked[v] = true;id[v] = count;size[count]++;q.enqueue(v);while (!q.isEmpty()) {Integer x = q.dequeue();for (Integer w : graph.adj(x)) {if (!marked[w]) {marked[w] = true;id[w] = count;size[count]++;q.enqueue(w);}}}}/*** 给定顶点所在的连通分量标记* @param v 给定顶点* @return 顶点所在的连通分量标记* @throws IllegalArgumentException unless {@code 0<= v < V}*/public int id(int v) {validateVertex(v);return id[v];}/*** 顶点v和w是否连通(是否在同一个连通分量内)* @param v 顶点v* @param w 顶点w* @return  {@code true} 如果{@code v}和{@code w}在同一个连通分量内;否则{@code false}* @throws IllegalArgumentException unless {@code 0 <= v < V}* @throws IllegalArgumentException unless {@code 0 <= w < V}*/public boolean connected(int v, int w) {validateVertex(v);validateVertex(w);// 如果v和w在同一连通分量,那么连通分量标记相等;否则falsereturn id[v] == id[w];}/*** 返回无向图{@code graph}中连通分量数量* @return  返回无向图{@code graph}中连通分量数量*/public int count() {return count;}/*** 检查指定的顶点是否是有效顶点* @param v 给定顶点* @throws IllegalArgumentException unless {@code 0<= v < V}*/private void validateVertex(int v) {int V = marked.length;if (v < 0 || v >= V) {throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1));}}public void display() {Map<Integer, ArrayList<Integer>> map = new HashMap<>(count);for (int i = 0; i < count; i++) {map.put(i, new ArrayList<>());}for (int i = 0; i < id.length; i++) {int k = id[i];ArrayList<Integer> list = map.get(k);list.add(i);map.put(k, list);}System.out.println("分量标记\t顶点数量\t顶点");for (int i = 0; i < count; i++) {ArrayList<Integer> l = map.get(i);System.out.println(i +"\t\t" + l.size() + "\t\t" + l);}}
}

这里广度优先搜索和深度优先搜索都能完成连通分量的搜索和标记,这里以广度优先搜索为例,简单讲解下算法。

说明:

  1. 算法第四版给出的是深度优先的递归版本实现,我们这里给出了非递归的广度优先搜索和深度优先搜索实现。
  2. 每次bfs(q, v)一定能保证完成包含顶点v的这个连通分量的搜索,这样外层for遍历所有顶点,在该连通分量的顶点(被标记)不在执行bfs;不在该连通分量的顶点(未被标记),一定是属于其他连通分量。直至遍历结束。
  3. bsf(q,v)通过先标记起点v,在标记和顶点v距离1条边的顶点,2条边的顶点,依次类推,直到标记所有连通的顶点。
  4. bfs(q, v)内顶点都属于同一连通分量,id[]记录这些顶点对应的连通分量标记就相同;每标记一个顶点,相应的记录该连通分量size[]顶点数量+1。

思考:

  1. 这里为什么即可以用广度优先又可以用深度优先呢?

命题C。深度优先搜索和广度优先搜索的预处理使用的时间和空间与V+E成正比且可以在常数时间内处理关于图的连通性查询。

证明。有代码可以知道每个邻接表的元素都只会被检查一次,共有2E个元素(每条边2个)。

测试

测试代码:

public static void testCC() {String path = "H:\\gaogzhen\\java\\projects\\algorithm\\asserts\\tinyG.txt";In in = new In(path);Graph graph = new Graph(in);CC cc = new CC(graph);int v = 0, w = 5;System.out.println("顶点 " + v + " 和顶点 " + w + "是否连通:" + cc.connected(v, w));System.out.println("顶点 " + w + "连通分量标记:" + cc.id(w));System.out.println("连通分量数量:" + cc.count());cc.display();
}

测试结果:

顶点 0 和顶点 5是否连通:true
顶点 5连通分量标记:0
连通分量数量:3
分量标记	顶点数量	顶点
0		7		[0, 1, 2, 3, 4, 5, 6]
1		2		[7, 8]
2		4		[9, 10, 11, 12]

后记

如果小伙伴什么问题或者指教,欢迎交流。

❓QQ:806797785

⭐️源代码仓库地址:https://gitee.com/gaogzhen/algorithm

参考链接:

[1][美]Robert Sedgewich,[美]Kevin Wayne著;谢路云译.算法:第4版[M].北京:人民邮电出版社,2012.10.p344-348.

相关文章:

0107连通分量-无向图-数据结构和算法(Java)

文章目录1 API2 代码实现和分析测试后记1 API 深度优先搜索下一个直接应用就是找出一幅图中的连通分量,定义如下API。 public class CCCC(Graph g)预处理构造函数booleanconnected(int v, int w)v和w连通吗intcount()连通分量数intid(int v)v所在的连通分量标识符(0~count()-…...

[学习笔记]黑马程序员python教程

文章目录思维导图Python基础知识图谱面向对象SQL入门和实战Python高阶技巧第一阶段第九章&#xff1a;Python异常、模块与包1.9.1异常的捕获1.9.1.1 为什么要捕获异常1.9.1.2 捕获常规的异常1.9.1.3 捕获指定的异常1.9.1.4 捕获多个异常1.9.1.5 捕获全部异常1.9.1.6 异常的else…...

如何配置用于构建 FastReport Online Designer 的 API ?

FastReport Online Designer 是一个跨平台的报表设计器&#xff0c;允许通过任何平台的移动设备创建和编辑报表。今天我们就一起来看看在2023版中新增和改进的功能有哪些&#xff0c;点击下方可以获取最新版免费试用哦&#xff01; FastReport Onlin Designe最新版试用https:/…...

【嵌入式Linux内核驱动】02_字符设备驱动

字符设备驱动 〇、基本知识 设备驱动分类 &#xff08;按共性分类方便管理&#xff09; 1.字符设备驱动 字符设备指那些必须按字节流传输&#xff0c;以串行顺序依次进行访问的设备。它们是我们日常最常见的驱动了&#xff0c;像鼠标、键盘、打印机、触摸屏&#xff0c;还有…...

【零散整理】

1-1 git查看代码的项目总行数 git log --prettytformat: --numstat | awk ‘{ add $1; subs $2; loc $1 - $2 } END { printf “added lines: %s, removed lines: %s, total lines: %s\n”, add, subs, loc }’ - 1-2 cookie const cookies document.cookie.split(; )for…...

RocketMQ重复消费的症状以及解决方案

RocketMQ重复消费的症状以及解决方案 生产消息时重复 症状 当一条消息已被成功发送到 消费者 并完成持久化&#xff0c;此时出现了网络闪断或者客户端宕机&#xff0c;导致服务端对客户端应答失败。 如果此时 生产者 意识到消息发送失败并尝试再次发送消息&#xff0c;消费者…...

数字化时代,企业的商业模式建设

随着新一代信息化、数字化技术的应用&#xff0c;众多领域通过科技革命和产业革命实现了深度化的数字改造&#xff0c;进入到以数据为核心驱动力的&#xff0c;全新的数据处理时代&#xff0c;并通过业务系统、商业智能BI等数字化技术和应用实现了数据价值&#xff0c;从数字经…...

项目实战典型案例23——-注册上nacos上的部分服务总是出现频繁掉线的情况

注册上nacos上的部分服务总是出现频繁掉线的情况一&#xff1a;背景介绍二&#xff1a;思路&方案解决问题过程涉及到的知识nacos服务注册和服务发现一&#xff1a;背景介绍 spring cloud项目通过nacos作为服务中心和配置中心&#xff0c;出现的问题是其中几个服务总是出现…...

玩转金山文档 3分钟让你的文档智能化

在上个月底&#xff0c;我们给大家推荐了金山轻维表的几个使用场景&#xff0c;社群中不少用户反响很好&#xff0c;对其中一些场景的解决方案十分感兴趣。但也有一些人表示&#xff0c;有些场景不知道如何实现&#xff0c;希望我们能提供模版/教程。这次我们将做一期热门模板盘…...

安装了nodejs怎么安装nvm

第一步&#xff0c;从控制面板卸载已经安装的node 第二步&#xff0c;删除C盘program开头文件夹下的node文件 第三步&#xff0c;去C/user/用户名 文件夹下&#xff0c;删除.npmrc文件 第四步&#xff0c;打开隐藏文件&#xff0c;第三步文件夹下有一个Appdata文件&#xff…...

java安全编码规范考试

java安全编码规范考试 整理不易&#xff0c;收点币&#xff01;&#xff01; 安全编码规范考试.md 下面对zip文件的安全解压缩描述&#xff0c;错误的是 A.zip文件解压时&#xff0c;可以使用entry.getSize(&#xff09;对解压缩文件进行文件大小判断 B.zip文件解压时&…...

表格检测识别技术的发展历程

近年来&#xff0c;随着计算机技术的飞速发展&#xff0c;越来越多的研究者开始关注表格检测识别技术。表格检测识别技术是一种利用计算机自动处理表格的技术&#xff0c;它可以实现从文本中检测出表格&#xff0c;并进行识别和提取。这种技术有助于提高文本处理的效率&#xf…...

设计UI - Adobe xd对象介绍

矩形工具 新建矩形 操作步骤&#xff1a;选择矩形工具&#xff0c;快捷键R&#xff0c;鼠标在画板上拖出矩形即可。 拖动定界框周围圆形手柄&#xff0c;可快速调整矩形大小&#xff0c;也可以输入宽和高的参数对矩形大小进行改变。 移动矩形 操作步骤&#xff1a;选择选择工具…...

优思学院|精益生产中的“单件流”真的能够做到吗?

精益生产中提到的“一个流”&#xff08;One Piece Flow&#xff09;是一种生产方式&#xff0c;它的核心理念是通过合理配置作业场地、人员和设备&#xff0c;使产品从投入到成品产出的整个制造加工过程中始终处于不停滞、不堆积、不超越&#xff0c;按节拍一个一个地流动。 …...

移除元素问题解决方法------LeetCode-OJ题

问题&#xff1a; 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 要求&#xff1a; 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改…...

JavaScript学习笔记(1.0)

push() 语法&#xff1a;数组.push(数据) 作用&#xff1a;将数据追加到数组的末尾 返回值&#xff1a;追加数据后数组最新的长度 pop() 语法&#xff1a;数组.pop() 作用&#xff1a;删除数组最后一个数据 返回值&#xff1a;被删除的数据 unshift() 语法&#xff1a;数…...

FCN网络介绍

目录前言一.FCN网络二.网络创新点前言 在图像分割领域&#xff0c;有很多经典的网络&#xff0c;如MASK R-CNN&#xff0c;U-Net&#xff0c;SegNet&#xff0c;DeepLab等网络都是以FCN为基础进行设计的。我们这里简单介绍一下这个网络。 一.FCN网络 FCN网络介绍   FCN 即全…...

Idea+maven+spring-cloud项目搭建系列--11 整合dubbo

前言&#xff1a; 微服务之间通信框架dubbo&#xff0c;使用netty &#xff08;NIO 模型&#xff09;完成RPC 接口调用&#xff1b; 1 dubbo 介绍&#xff1a; Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题&#xff0c;官方提…...

2023年上半年北京杭州/广州深圳软考中/高级报名入口

软考是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资格考试。 系统集成…...

jupyter notebook配置和使用

简介 Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算&#xff1a;开发、文档编写、运行代码和展示结果。 参考博客&#xff1a;https://zhuanlan.zhihu.com/p/33105153 特点 ①编程时具有语法高亮、缩进、tab补全的功能。 ② 可直接通过浏览器…...

【C++】通过stack、queue、deque理解适配器模式

破镜不能重圆&#xff0c;枯木可以逢春。 文章目录一、stack1.stack的介绍2.stack相关OJ题&#xff08;巧妙利用stack数据结构的特征&#xff09;3.stack的模拟实现二、queue1.queue的介绍2.queue的相关OJ题&#xff08;巧妙利用queue数据结构的特征&#xff09;3.queue的模拟实…...

JavaScript 高级实例集合

文章目录JavaScript 高级实例集合创建一个欢迎 cookie简单的计时另一个简单的计时在一个无穷循环中的计时事件带有停止按钮的无穷循环中的计时事件使用计时事件制作的钟表创建对象的实例创建用于对象的模板JavaScript 高级实例集合 创建一个欢迎 cookie 源码 <!DOCTYPE ht…...

Flutter(五)容器类组件

布局类组件包含多个子组件&#xff0c;而容器类组件只包含一个子组件 目录填充&#xff08;Padding&#xff09;装饰容器&#xff08;DecoratedBox&#xff09;变换&#xff08;Transform&#xff09;Transform.translate 平移Transform.rotate 旋转Transform.scale 缩放Rotate…...

实现满屏品字布局

html, body {width: 100%;height: 100%;}.first {width: 50%;height: 50%;margin: auto;background-color: pink;}.second {width: 50%;height: 50%;float: left;background-color: greenyellow;}.third {width: 50%;height: 50%;float: left;background-color: yellow;}...

软件测试-性能测试-基础知识

文章目录 1.性能测试理论1.1 相关概念1.2 性能测试指标2.性能测试策略2.1 基准测试2.2 负载测试2.3 稳定性测试2.4 其他测试策略3.性能测试的流程3.1 需求分析3.2 编写性能测试计划和方案3.3 编写性能测试用例3.4 性能测试执行3.5 性能测试报告4.性能测试工具4.1 Loadrunner4.2…...

java多线程与线程池-02线程池与锁

线程池与锁 第4章 线程池入门 4.1 ThreadPoolExecutor ThreadPoolExecutor是应用最广的底层线程池类,它实现了Executor和ExecutorService接口。 4.1.1 创建线程池 下面创建一个线程池,通过调整线程池构造函数的参数来了解线程池的运行特性。把核心线程数设置为3,最大…...

AB测试——流程介绍(设计实验)

前言&#xff1a; 作为AB测试的学习记录&#xff0c;接上文内容&#xff0c; 本文继续介绍假设建立和实验设计部分&#xff0c;包括实验对象、样本量计算&#xff08;显著性水平、统计功效及最小可检测效应&#xff09;、实验周期。 相关文章&#xff1a; AB测试——原理介绍 A…...

C++中的智能指针有哪些?分别解决的问题以及区别?

1.C中的智能指针有4种&#xff0c;分别为&#xff1a;shared_ptr、unique_ptr、weak_ptr、auto_ptr&#xff0c;其中auto_ptr被C11弃用。 2.使用智能指针的原因 申请的空间&#xff08;即new出来的空间&#xff09;&#xff0c;在使用结束时&#xff0c;需要delete掉&#xff0…...

通达信捉妖改良CCI指标公式,简洁巧妙

高端的食材&#xff0c;往往只需要简单的烹饪方式。好的指标也是一样&#xff0c;只需要简单处理&#xff0c;就可以实现不错的效果。捉妖改良CCI指标公式属于意外之喜&#xff0c;编写指标时写错了&#xff0c;研究后发现结果比原想法更好。 捉妖改良CCI指标公式利用了CCI&am…...

「Python 基础」面向对象编程

文章目录1. 面向对象编程类和实例访问限制继承和多态type()isinstance()dir()实例属性和类属性2. 面向对象高级编程\_\_slots\_\_property多重继承定制类枚举类元类1. 面向对象编程 Object Oriented Programming 简称 OOP&#xff0c;一种程序设计思想&#xff0c;以对象为程…...

网站建设服务器搭建/seo云优化外包

北京航空航天大学数字电路与计算机组成原理试题(2001年)一、(3’4’3’)1)用卡诺图化简下列逻辑函数&#xff1a;其约束条件为&#xff1a;C(D12)一个3:8译码器构成的逻辑电路如图1所示&#xff0c;写出逻辑函数F1、F2的表达式。图13)试分析图2所示电路的逻辑功能&#xff0c;并…...

网站开发广告/武汉seo网络营销推广

点击关注“有赞coder”获取更多技术干货哦&#xff5e;作者&#xff1a;郝加升部门&#xff1a;增长中心-前端在2020年7月7日微信小程序低调的开放了一个功能&#xff0c;微信小程序“分享到朋友圈”。最近被产品提了相关需求&#xff0c;过程中遇到了一些坑。作者带着踩坑经验…...

用java做计算机销售网站开发/成人企业管理培训课程

我用python 2.7中的socket模块编写了一个客户机和服务器代码。问题是我不知道/无法发送服务器响应。这是我的客户代码&#xff1a;import socketfrom optparse import OptionParserdef main():sock Noneparser OptionParser()parser.add_option("-z", action"…...

北京微信网站制作费用/网络策划

1.老师您好&#xff01;我所用的数据是动态面板&#xff0c;想用系统GMM和差分GMM进行估计&#xff0c;模型为&#xff1a;Ya0a1X1a2X2a3X1X2其中&#xff0c;X1是内生变量&#xff0c;X2为外生变量&#xff0c;X1X2为二者交互项&#xff0c;请问&#xff1a;由于X1是内生变量&…...

怎样做金融网站/搜索关键词的方法

一、问题描述 当引用第三方.cpp/.h文件到VC 2019的MFC项目中&#xff0c;编译时总会报忘记向源中添加“#include “pch.h””的报错提醒。 详细错误为&#xff1a; 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C1010 在查找预编译头时遇到意外的文件结尾。是否忘记了向…...

广州手机网站制作/百度新版本更新下载

笔者在项目中遇到过获取本机网卡ip的例子&#xff0c;利用python库psutil解决了此问题。 def get_netcard():"""获取网卡名称和ip地址"""netcard_info []info psutil.net_if_addrs()for k, v in info.items():for item in v:if item[0] 2 and…...