上一章我大概说明了什么是图论以及无向图的基础概念,本章我们要研究一种更普遍的算法——连通性算法。它属于图论的分支,也是一种抽象算法。在深入算法之前,我们先提出一个具体的问题:假设在空间中存在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)的更多相关文章

  1. 对象模型图(OMD)阅读指南

    樱木 原文 对象模型图(OMD)阅读指南(转载) 补充几个名词概念: UML:Unified Modeling Language 统一建模语言,是用来对软件密集系统进行可视化建模的一种语言.UML为面 ...

  2. QQ小橙团队排表机器人使用方法

    版权声明 别瞎JB玩坏了...一个群一个群导入很累的 联系QQ: 986859110 目录 网页版使用说明 登录和权限操作 团队和模板选择操作 模板使用案例 团队面板操作 老板管理 人员管理 QQ群机 ...

  3. 微信小程序把玩(三十三)Record API

    原文:微信小程序把玩(三十三)Record API 其实这个API也挺奇葩的,录音结束后success不走,complete不走,fail也不走, 不知道是不是因为电脑测试的原因,只能等公测或者等他们 ...

  4. 微信小程序把玩(二十三)modal组件

    原文:微信小程序把玩(二十三)modal组件 modal弹出框常用在提示一些信息比如:退出应用,清楚缓存,修改资料提交时一些提示等等. 常用属性: wxml <!--监听button点击事件-- ...

  5. 清橙 A1206 小Z的袜子(莫队算法)

    A1206. 小Z的袜子 时间限制:1.0s   内存限制:512.0MB   总提交次数:1357   AC次数:406   平均分:46.75   将本题分享到:        查看未格式化的试题 ...

  6. 转:苹果Xcode帮助文档阅读指南

    一直想写这么一个东西,长期以来我发现很多初学者的问题在于不掌握学习的方法,所以,Xcode那么好的SDK文档摆在那里,对他们也起不到什么太大的作用.从论坛.微博等等地方看到的初学者提出的问题,也暴露出 ...

  7. 数据结构看书笔记(二)--算法(Algorithm)简介

    算法:是解决问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作. 算法的特性:算法具有五个特性:输入.输出.有穷性.确定性.可行性 输入输出:算法具有零个或多个输入:至 ...

  8. 两百条微信小程序跳坑指南(不定时更新)

    微信小程序联盟出品 跳坑textarea<二百二十三>不显示文本及textarea相关问题集合跳坑<二百一十三> background-image无法获取本地资源图片....跳 ...

  9. 算法竞赛进阶指南 0x00 基本算法

    放在原来这个地方不太方便,影响阅读体验.为了读者能更好的刷题,另起一篇随笔. 0x00 基本算法 0x01 位运算 [题目][64位整数乘法] 知识点:快速幂思想的灵活运用 [题目][最短Hamilt ...

随机推荐

  1. OpenCV中对Mat里面depth,dims,channels,step,data,elemSize和数据地址计算的理解 (转)

    cv::Matdepth/dims/channels/step/data/elemSizeThe class Mat represents an n-dimensional dense numeric ...

  2. 026-chmod命令

    语法# chmod [ 选项参数 ]  选择修改权限的对象   权限的改变   目标文件 语义:对哪些目标文件的哪些权限进行修改. (1)# chmod -R ugo +r /home/apple.将 ...

  3. discuz注册页修改

    大家好!近来备受发帖机困扰,备受垃圾帖子困扰.一直以来都纯粹在删帖当中,本来网站服务器就是国内服务器,这样一来很多关键字是禁止的,可不管如何设置防灌水还是无法杜绝这一事项,特别是国内空间的网站,一出现 ...

  4. readyState与status

    XMLHttpRequest对象(Ajax)的状态码(readystate) 当一个XMLHttpRequest初次创建时,这个属性的值是从0开始,知道接收完整的HTTP响应,这个值增加到4.有五种状 ...

  5. BFC的概念及作用

    在了解什么是BFC之前,首先得明白什么是Box , Formatting Context (一个决定如何渲染文档的容器)的概念 Box: CSS布局的基本单位 Box是 CSS 布局的对象和基本单位, ...

  6. centos 安装 ffmpeg

    使用yum方式安装ffmpeg: 先安装Nux Dextop仓库: Nux Dextop库依赖于EPEL库,所有要先安装EPEL库(需要管理员权限). 如果安装过则跳过. $ su root $ yu ...

  7. 20145329 《网络对抗技术》MSF基础应用

    实践目标 掌握metasploit的基本应用方式,掌握常用的三种攻击方式的思路.具体需要完成(1)一个主动攻击,如ms08_067;(2)一个针对浏览器的攻击,如ms11_050:(3)一个针对客户端 ...

  8. 20165211 获奖感想及java课程总结

    20165211 获奖感想及java课程总结 理论脱离实践是最大的不幸.--达芬奇 这句话,是我在学习Java之前,假期内写的20165211 学习基础和C语言调查里的所引用的一句话,是当时我对Jav ...

  9. Java位运算实现加减乘除

    一.加法 a+b 举例实现:13+9=22 13+9不考虑进位结果为12 只考虑进位结果为10 和刚好是22. 13二进制为1101,9二进制为1001. 不考虑进位结果为0100.算式为a^b 只考 ...

  10. Bootloader之uBoot简介

    本文转载自:http://blog.ednchina.com/hhuwxf/1915416/message.aspx 一.Bootloader的引入 从前面的硬件实验可以知道,系统上电之后,需要一段程 ...