小橙书阅读指南(十三)——连通性算法(union-find)
上一章我大概说明了什么是图论以及无向图的基础概念,本章我们要研究一种更普遍的算法——连通性算法。它属于图论的分支,也是一种抽象算法。在深入算法之前,我们先提出一个具体的问题:假设在空间中存在N个点,我们可以通过线段连接任意两点,相互连接的点属于同一组连通分量,我们如何计算点p和点q之间是否连通。算法的核心是:如何表示连通性以及如何检查连通性。
下面提供算法的抽象接口:
/**
* 连通性算法
*/
public interface UnionFind {
/**
* p点和q点之间添加一条通路
*
* @param p
* @param q
*/
void union(int p, int q); /**
* 获取p点的连通分量
*
* @param p
* @return
*/
int find(int p); /**
* 判断p点和q点是否存在一条通路
*
* @param p
* @param q
* @return
*/
boolean connected(int p, int q); /**
* 连通分量的数量
*
* @return
*/
int count();
}
一、快速查询算法Quick-Find
我们将空间中的点这一概念抽象成int[](整形数组),i代表不同的点int[i]代表不同的连通分量。一种比较容易理解的想法是,从属于同一组连通分量的任一点p和q必定int[p]等于int[q]。因此当我们需要查询点p和q是否连通的时候只需要判断int[p] == int[q]是否成立即可。
/**
* 连通性算法:quick-find
*/
public class QuickFind implements UnionFind {
private int[] id; // 分量id
private int count; public QuickFind(int n) {
count = n;
id = new int[n];
for (int i = 0; i < n; i++) {
id[i] = i;
}
} @Override
public void union(int p, int q) {
int pID = find(p);
int qID = find(q); if(pID == qID) {
return;
}
for(int i = 0;i < id.length; i++) {
if(id[i] == pID) {
id[i] = qID;
}
}
count--;
} @Override
public int find(int p) {
return id[p];
} @Override
public boolean connected(int p, int q) {
return find(p) == find(q);
} @Override
public int count() {
return count;
}
}
find()操作的速度显然是很快的,因为它只需要访问id[]数组一次。但是对于每一对数组union()都需要扫描整个id[]数组。因此quick-find算法一般无法处理大型数组。
算法图示:

二、快速连接算法Quick-Union
我们要讨论的下一个算法的重点是提高union()方法的速度,为此可能会稍微牺牲一下find()的效率,但是通常情况下这样做是值得的。Quick-Union算法考虑把属于同一组连通分量的点连接成一棵树,i代表点,int[i]代表i的父节点,根节点p等于int[p]。
public class QuickUnion implements UnionFind {
private int count;
private int[] id;
public QuickUnion(int n) {
count = n;
id = new int[n];
for(int i = 0; i < n; i++) {
id[i] = i;
}
}
@Override
public void union(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if(pRoot == qRoot) {
return;
}
id[pRoot] = qRoot;
count--;
}
@Override
public int find(int p) {
while(p != id[p]) {
p = id[p];
}
return p;
}
@Override
public boolean connected(int p, int q) {
return false;
}
@Override
public int count() {
return 0;
}
}
快速连接算法的每一次连接会分别遍历两次连通分量,在连通分量中包含元素数量相对总数而言比较小的情况下可以提供非常不错的速度。
算法图示:

事实上,无论是Quick-Find算法还是Quick-Union算法,他们在图论的基础上基本是起到相互补充的作用。更重要的一点是,我们通过对他们的学习可以认识到,十全十美的算法很难实现,更多的时候算法针对某一个问题的痛点才是有效的。
小橙书阅读指南(十三)——连通性算法(union-find)的更多相关文章
- 对象模型图(OMD)阅读指南
樱木 原文 对象模型图(OMD)阅读指南(转载) 补充几个名词概念: UML:Unified Modeling Language 统一建模语言,是用来对软件密集系统进行可视化建模的一种语言.UML为面 ...
- QQ小橙团队排表机器人使用方法
版权声明 别瞎JB玩坏了...一个群一个群导入很累的 联系QQ: 986859110 目录 网页版使用说明 登录和权限操作 团队和模板选择操作 模板使用案例 团队面板操作 老板管理 人员管理 QQ群机 ...
- 微信小程序把玩(三十三)Record API
原文:微信小程序把玩(三十三)Record API 其实这个API也挺奇葩的,录音结束后success不走,complete不走,fail也不走, 不知道是不是因为电脑测试的原因,只能等公测或者等他们 ...
- 微信小程序把玩(二十三)modal组件
原文:微信小程序把玩(二十三)modal组件 modal弹出框常用在提示一些信息比如:退出应用,清楚缓存,修改资料提交时一些提示等等. 常用属性: wxml <!--监听button点击事件-- ...
- 清橙 A1206 小Z的袜子(莫队算法)
A1206. 小Z的袜子 时间限制:1.0s 内存限制:512.0MB 总提交次数:1357 AC次数:406 平均分:46.75 将本题分享到: 查看未格式化的试题 ...
- 转:苹果Xcode帮助文档阅读指南
一直想写这么一个东西,长期以来我发现很多初学者的问题在于不掌握学习的方法,所以,Xcode那么好的SDK文档摆在那里,对他们也起不到什么太大的作用.从论坛.微博等等地方看到的初学者提出的问题,也暴露出 ...
- 数据结构看书笔记(二)--算法(Algorithm)简介
算法:是解决问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作. 算法的特性:算法具有五个特性:输入.输出.有穷性.确定性.可行性 输入输出:算法具有零个或多个输入:至 ...
- 两百条微信小程序跳坑指南(不定时更新)
微信小程序联盟出品 跳坑textarea<二百二十三>不显示文本及textarea相关问题集合跳坑<二百一十三> background-image无法获取本地资源图片....跳 ...
- 算法竞赛进阶指南 0x00 基本算法
放在原来这个地方不太方便,影响阅读体验.为了读者能更好的刷题,另起一篇随笔. 0x00 基本算法 0x01 位运算 [题目][64位整数乘法] 知识点:快速幂思想的灵活运用 [题目][最短Hamilt ...
随机推荐
- 9/24matplotlib使用入门
---恢复内容开始--- matplotlib的使用中有好几种输出风格,有matlab风格,和官方文档的as风格,各有所长,本文对比介绍官方文档中的使用风格. 我们画图的目的是要将函数以图像显示出来, ...
- #C语言初学记录(位运算)
位运算 Problem Description7-1 数组元素循环右移问题 一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由 ...
- 171. Excel Sheet Column Number(简单数学题)
Given a column title as appear in an Excel sheet, return its corresponding column number. For exampl ...
- 76. Minimum Window Substring(hard 双指针)
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- Linux命令: 查找文件中的字符串
①cat filename | grep 'string' ②编辑模式查找,/string, 依次敲入下面的命令 vim filename e i ESC /string 从光标位置开始往后查找第一个 ...
- redis安装及注意事项
在linux中使用wget时,若报-bash: wget: command not found,则表明没有安装wget,需要安装,安装命令如下: yum -y install wget 安装完成即可以 ...
- appium自动化测试实战
一.Appium的介绍 Appium是一款开源的自动化测试工具,其支持iOS和安卓平台上的原生的,基于移动浏览器的,混合的应用. 1. 使用appium进行自动化测试的好处 Appium在不同平台 ...
- Python入门之Python Colorama模块
Python的Colorama模块,可以跨多终端,显示字体不同的颜色和背景,只需要导入colorama模块即可,不用再每次都像linux一样指定颜色: 官方参考:https://pypi.org/pr ...
- 08: CORS实现跨域请求
目录: 1.1 cors跨域请求介绍 1.2 使用tornado实现 复杂请求 1.3 Django中使用django-cors-headers解决跨域问题 1.1 cors跨域请求介绍返回顶部 1. ...
- 三星核S5PV210AH-A0 SAMSUNG
三星S5PV210AH-A0 S5PV210又名“蜂鸟”(Hummingbird),是三星推出的一款适用于智能手机和平板电脑等多媒体设备的应用处理器,S5PV210和S5PC110功能一样,110小封 ...