union-find算法分析(1)
详细解析参照算法(第4版)1.5章——案例研究:union—find算法
1.union-find法的API
public class UF UF(int N) 以整数标识(0—N-1)初始化N个标识 void union(int p,int q) 在触点p和q之间添加一条连接 void find(int p) p所在连通分量的标识符(0—N-1) void connected(int p,int q) 判断触点p和q是否连通,即p和q是否在同一连通分量 int count() 连通分量的数目 2.union-find的实现
1: public abstract class UF {2: protected int count;3: protected int[] id;4:5: public UF(int N) {6: count = N;27: if (find(i) == pID)7: id = new int[N];8: for (int i = 0; i < N; i++)9: id[i] = i;10: }11:12: public abstract int find(int p);13:14: public abstract void union(int p,int q);15:16: public boolean connected(int p,int q){17: return find(p) == find(q);18: }19:20: public int count(){21: return count;22: }23: }2.1.quick-find算法
1: public class QuickFindUF extends UF {2:3: public QuickFindUF(int N) {4: super(N);5: }6:7: @Override8: public int find(int p) {9: // TODO Auto-generated method stub10: // 触点p为索引,id[p]即是p所在的连通分量的标识符11: return id[p];12: }13:14: /**15: * 如果p和q在同一个连通分量,则p和q连通 否则,要将p和q连通(两个连通分量合并),即将p的连通分量所有触点的连通分量改成q的连通分量16: */17: @Override18: public void union(int p, int q) {19: // TODO Auto-generated method stub20: int pID = find(p);21: int qID = find(q);22:23: if (pID == qID)24: return;25:26: for (int i = 0; i < id.length; i++)27: if (find(i) == pID)28: id[i] = qID;29: count--;30: }31:32:33:34: }算法分析
1.union(p,q)会访问数组次数N+3~2N+1
分析:(1)两次find()操作,访问2次数组
(2)扫描整个数组id[],判断p和q是否在同一个连通f分量if(find(i)==pID),访问N次数组
(3)①只有p,其余触点均不和p在同一连通分量 id[p] =qID,访问1次数组
②除了q本身,其余均和p在同一连通分量 id[i] = qID(i≠q),访问 N-1次数组,故总的访问次数①2+N+1 = N+3 ②2+N+N-1 = 2N+1
2.在最好的情况下(union(p,q)访问数组N+3次),N个整数要进行N-1次合并union(p,q)操作,访问数组(N+3)(N-1)~N^2。
quick-union算法是平方级别的。
测试结果
1: public static void main(String[] args) {2: DirectInput.directInput(args);3: int N = StdIn.readInt();4: UF uf = new QuickFindUF(N);5: while(!StdIn.isEmpty()){6: int p = StdIn.readInt();7: int q = StdIn.readInt();8: if(uf.connected(p, q) ) continue;9: uf.union(p, q);10: StdOut.println(p+ " " + q);11: }12:13: StdOut.println(uf.count() + " components");14: }
2.2.quick-union算法
1: /**2: * 以触点p为索引的数组id[p]是p所在的连通分量中的另一个触点q<br>3: * 即p与q是连通的4: *5: * @author YoungCold6: *7: */8: public class QuickUnionUF extends UF {9:10: public QuickUnionUF(int N) {11: super(N);12: }13:14: /**15: * 找到p的根触点<br>16: * 根触点:符合id[p]=p,即指向自己的触点,即为根触点17: */18: @Override19: public int find(int p) {20: // TODO Auto-generated method stub21: while (p != id[p])22: p = id[p];23: return p;24: }25:26: /**27: * 当p的根触点和q的根触点不同时,说明p和q不在同一个连通分量<br>28: * 要想p和q连通,即将p(q)的根触点(id值为本身)指向q(p)的根触点29: */30: @Override31: public void union(int p, int q) {32: // TODO Auto-generated method stub33: int pRoot = find(p);34: int qRoot = find(q);35:36: if (pRoot == qRoot)37: return;38:39: // 将p的根触点(id值为本身)指向q的根触点40: id[pRoot] = qRoot;41: //每次合并,连通分量的数目减一42: count--;43: }44:45: public static void main(String[] args) {46: DirectInput.directInput(args);47: int N = StdIn.readInt();48: UF uf = new QuickUnionUF(N);49: for (int i = 0; i < N; i++) {50: int p = StdIn.readInt();51: int q = StdIn.readInt();52: if (uf.connected(p, q))53: continue;54:55: uf.union(p, q);56: StdOut.println(p + " " + q);57: }58: StdOut.println(uf.count() + " components");59: }60:61: }(1)与quick-find不同的是,以触点p为索引的数组id[]不再表示p所在的连通分量,而是表示p所在的连通分量的另一个触点(也可能是它本身),当它是本身时,该触点就是根触点,也就是连通分量所对应的树的根节点,这种联系称之为链接。
(2)森林的表示,实际上id[]数组用父链接的形式表示了一片森林。无论从任何触点所对应的节点开始跟踪链接,最终都能到达含有该节点的树的根节点(可用数学归纳法证明)。
算法分析
1.quick-union算法看似比quick-find算法块,因为它不需要为每对输入遍历整个数组。
2.①最好的情况下find(p),仅访问一次数组,此时触点p为根触点。
②最坏的情况下find(p),访问数组2N-1次
while(p != id[p]) p = id[p];
最坏的情况是触点p所在的连通分量对应的树退化成线性表而且仅有一个连通分量,而p在线性表的表尾。
while()循环的判断条件要访问N次数组,while()循环的执行体要访问N-1 次数组(当最后一次到达根节点时,不执行循环体)。共2N-1次。
3.由此可见,find(p)访问数组的次数,是由触点p对应的节点在树的高度所决定的。设p在树的中的高度为h,则访问数组的次数为2h+1次。
4.假设输入的是有序整数对0-1、0-2、0-3…0-N,N-1对之后的N个触点将全 部处于同一个连通分量内(详见main()),且由quick-union算法得到的树的高度为N-1,其中0→1,1→2…N-1→N。
对于整数对0-i,执行union(0,i),将访问2i+1次数组。
①其中0的根触点是i-1,高度是i-1,根据3,find(0)访问数组2i-1次
②其中i的根触点是i,高度是0,根据3,find(i)访问数组1次
③将i-1的根触点(原指向本身,现指向触点i)的数组内容变成i,访问数组1次
PS:书上是2i+2次,我分析是0-i是连通的,这样0的根触点是i,i的根触点是i,find(0)访问2i+1次,find(i)访问1次
共2i+2次。
可根据main()方法,此时0和i应该不连通才对。
5.处理N对整数所需的所有find()操作访问是;Σ(1→N)(2i) = 2(1+2+…N) ~N2
可以看出quick-union和quick-find都是平方级别的算法。
转载于:https://blog.51cto.com/youngcold/1106992
union-find算法分析(1)相关推荐
- union-find算法分析(2)
2.3.weighted-quick-union--加权quick-union算法 上篇的quick-union算法的效率之所以低(平方级别),最主要的原因是union(p,q)方法,随意将一棵树连接 ...
- 『算法』读书笔记 1.4算法分析 Part1
Chapter 1 本章结构 1.1Java语法 1.2数据抽象 1.3集合类抽象数据类型:背包 (Bags) .队列 (Queues) .栈 (Stacks) 1.4算法分析 1.5连通性问题-Ca ...
- 80211 发送速率选择算法分析
转:https://blog.csdn.net/junglefly/article/details/48974077 1. 介绍 <802.11无线网络权威指南 第二版>中对于选速和降速 ...
- 算法 c语言实现 英文版 pdf,数据结构与算法分析++C语言描述++英文版++..pdf-得力文库...
数据结构与算法分析++C语言描述++英文版++....pdf General Ination 书名数据结构与算法分析 C语言描述 英文版 第2版 作者(美)韦斯著 页数512 出版社机械工业出版社 出 ...
- Apriori 算法分析
Apriori 算法分析: 利用my_new_apriori.py文件,对杂货店商品进行关联规则挖掘,支持度=0.06,置信度=0.2 使用的数据集: 数据集下载地址: 链接:https://pan. ...
- Ralink WIFI driver发送速率选择算法分析
Ralink WIFI driver发送速率选择算法分析 380939960@qq.com 1. 介绍 <802.11无线网络权威指南 第二版>中对于选速和降速的描述: 市面上所有802 ...
- 一周搞定期末考系列之《算法分析与设计》
转眼就到了期末复习算法的时候了 真的是一点都不慌啊 算法分析与设计这门课,由于是一门选修课,而且我对算法分析没有过多的热爱,所以没有对这门课程进行全方位的深度的学习与复习,但是我相信,将下列算法的全部 ...
- Python type hints 之 Optional,Union
1,前言 type hint 在pep484加入,我个人觉得这种类似于类型约束的(机制)有点违背了python简单.简洁的初衷,在慢慢向c# java 这种强类型语言看齐的节奏. 不过好在不强制使用, ...
- C++ 共用体union 的使用
共用体是什么 共用体将不同的数据类型组织为一个整体, 需要注意的是,共用体在同一时刻只能存储一个数据成员的值., 共用体变量的地址和它的格式成员的地址都是同一地址 共用体的一般形式 union 共用体 ...
最新文章
- html 消息通知功能,HTML5之消息通知的使用(Web Notification)
- [转] Ubuntu/Linux Mint/Debian 安装 Java 8
- linux查看硬盘smart_SMART Utility for mac (硬盘检测)
- HEU 2036 Paths on a Grid
- ssh 连接超时 不断开
- mysql和php环境_php环境搭建wampserver、Apache、Mysql和php
- Java知识点详解 6 注解
- java获取屏幕截图
- 暑假第一战——java+mysql 个人信息管理系统
- java 安卓 物联网_面向物联网的Android应用开发与实践
- python-docx原有图片居中
- 期货开户交易所的手续费和查询方法
- U-Mail邮件网关智能DNS技术,解决海外邮件接收问题
- -转载-我要我们在一起故事原著
- 关于“上家公司离职原因”应聘者回答技巧分享
- 几种常见的服务器攻击类型
- Ubuntu 18.04安装全面战争三国游戏 (by quqi99)
- WebView中的视频全屏的相关操作
- sitecore系统教程之内容编辑器
- MDI窗体的优化---下
热门文章
- Android Studio 找不到EventBus/ButterKnife等第三方包解决方案
- windbg + sos 调试w3wp进程内存崩溃问题
- 【Solr】 solr对拼音搜索和拼音首字母搜索的支持
- tcpdump抓包分析具体解释
- UVA 11426 GCD-Extreme(II) ★ (欧拉函数)
- 串口项目——Cseiralport类的应用(1 )
- 装饰工程预结算教程电子书_东北分公司举行工程预结算实战技能培训
- NullPointerException int java.util.List.size()
- js动态创建对象_JS深浅拷贝的深入浅出
- java8 例外网站_Java8兰巴达斯和例外