Algorithm partI 第2节课 Union−Find
发展一个有效算法的具体(一般)过程:
union-find用来解决dynamic connectivity,下面主要讲quick find和quick union及其应用和改进。
基本操作:find/connected queries和union commands
动态连接性问题的场景:
1.1 建立模型(Model the problem):
关于object:0-N-1
关于连接的等价性:
关于连接块:
关于基本操作find query和union command:
比如union操作:
目标:
练习:
答案:C。最后剩下的连接块有{0,5,6}{3,4}{1,2,7,8,9}。
1.2 算法及其改进(Algorithm and improvement):
1.2.1 Quick Find
实现过程:
- public class QuickFindUF
- {
- private int[] id;
- public QuickFindUF(int N)
- {
- id = new int[N];
- for (int i = 0; i < N; i++)
- id[i] = i;
- }
- public boolean connected(int p, int q)
- { return id[p] == id[q]; }
- public void union(int p, int q)
- {
- int pid = id[p];
- int qid = id[q];
- for (int i = 0; i < id.length; i++)
- //这里有个约定:
- //p和q联合的时候,所有和p是一个连接块(connected conponents)的点的id都要设置为与id[q]相等
- if (id[i] == pid) id[i] = qid;
- }
- }
各个函数的时间复杂度:
弊端:
对N个实体做N次的union操作,时间复杂度是O(N2)。换言之,Quick find太慢,不适合大量的数据。
练习:
答案:C。最差情况就是除了id[q],其他元素都要改变。
1.2.2 Quick Union
说明:
实现过程:
- public class QuickUnionUF
- {
- private int[] id;//id[i],节点i的父节点
- public QuickFindUF(int N)
- {
- id = new int[N];
- //划分为N棵子树,每个子树的根节点就是本身
- for (int i = 0; i < N; i++)
- id[i] = i;
- }
- private int root(int i)//找打i所在子树的根节点
- {
- //如果id[i] == i,说明i是某一棵子树的根节点
- while (i != id[i]) i = id[i];
- return i;
- }
- public boolean connected(int p, int q)
- {
- return root(p) == root(q);
- }
- public void union(int p, int q)//将p所在子树的根节点的父节点设为q所在子树的根节点
- {
- int i = root(p);
- int j = root(q);
- id[i] = j;
- }
- }
各个操作的时间复杂度:注意quick union的union和find是最差情况(例如,形成的子树很高)的时间复杂度。
弊端:
练习:
答案:D。3的根节点是6:3->5->2->6。7的根节点是6:7->1->9->5->2->6。
练习:
答案:C
1.2.3 Weighted quick union
Improvement 1:weighting。为每个树保留track记录树的规模;union的时候将规模小的树的根节点添加为规模大的树的根节点的子节点。主要针对Quick union中容易出现树很高的情况。
实现过程:
- public class WeightedQuickUnionUF {
- private int[] id,sz;
- public WeightedQuickUnionUF(int N)
- {
- id = new int[N];
- sz = new int[N];//记录以i为根节点的树的节点个数
- for (int i = 0; i < N; i++)
- {
- sz[i] = 1;
- id[i] = i;
- }
- }
- private int root(int i)//和quick union相同
- {
- while (i != id[i]) i = id[i];
- return i;
- }
- public boolean connected(int p, int q)//和quick union相同
- {
- return root(p) == root(q);
- }
- public void union(int p, int q)
- {
- int i = root(p);
- int j = root(q);
- if (i == j) return;
- if (sz[i] < sz[j]){id[i] = j; sz[j] += sz[i];}
- else {id[j] = i; sz[i] += sz[j];}
- }
- }
各个函数的时间复杂度:注意到weighted quick union中的union和connected操作的时间复杂度都是log2N。
命题:按照Weighted quick union实现的树的任意一个节点的深度不会超过log2N。
证明:关注任意节点x。
1. 只有当包含x的子树T1作为lower tree被合并的时候,x的深度才有可能增加1。
2. 另一棵树T2,其中sz[T2]>=sz[T1]。
每合并1次,树的规模*2,并且最后的树的规模==N,所以x最多只能增加log2N次,意味着节点x最后的深度不会超过log2N。
Weighted quick union和Quick union的比较实例:
Weighted quick union实现结果更加均衡,叶节点到根的距离最大为4,每个节点到根节点的距离的平均要远远小于Quick union的结果。
1.2.4 Weighted quick union with path compressioin
Improvement 2:path compression。就是路径压缩。
实现过程有2种方式:主要区别是root函数的实现。
1. 找到当前点x的根节点后,将x与根节点相连路径上的所有节点的父节点设为根节点。
2. 在寻找当前点x的根节点的过程中,直接将x的父节点设置为x的父节点的父节点。
下面只展示union函数的实现:
方式1:
- private int root(int i)
- {
- if (id[i] == i) return i;//只有指向根节点才返回
- return id[i] = root(id[i]);
- }
方式2:
- private int root(int i)
- {
- while (i != id[i])
- {
- id[i] = id[id[i]];//指向父节点的父节点
- i = id[i];
- }
- return i;
- }
对N个点使用Weighted quick union with path compressioin中的union find操作m次的时间复杂度:
关于lg*的解释:http://stackoverflow.com/questions/2387656/what-is-olog-n/2387669
log* (n)- "log Star n" as known as "Iterated logarithm"
In simple word you can assume log* (n)= log(log(log(.....(log* (n))))
已经证明,union find问题的时间复杂度不可能到O(N)。
练习:
答案:
总结:
Algorithm partI 第2节课 Union−Find的更多相关文章
- centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更新 第三十节课
centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更 ...
- 风炫安全Web安全学习第十六节课 高权限sql注入getshell
风炫安全Web安全学习第十六节课 高权限sql注入getshell sql高权限getshell 前提条件: 需要知道目标网站绝对路径 目录具有写的权限 需要当前数据库用户开启了secure_file ...
- centos linux安全和调优 第四十一节课
centos linux安全和调优 第四十一节课 上半节课 Linux安全 下半节课 Linux调优 2015-07-01linux安全和调优 [复制链接]--http://www.apele ...
- centos shell编程6一些工作中实践脚本 nagios监控脚本 自定义zabbix脚本 mysql备份脚本 zabbix错误日志 直接送给bc做计算 gzip innobackupex/Xtrabackup 第四十节课
centos shell编程6一些工作中实践脚本 nagios监控脚本 自定义zabbix脚本 mysql备份脚本 zabbix错误日志 直接送给bc做计算 gzip innobacku ...
- [iOS]Objective-C 第一节课
Objective-C 第一节课 本节课的主要内容 创建Objective-C的第一个工程 HelloWorld Objective-C中的字符串 创建Objective-C的第一个工程 打开Xcod ...
- 《从零玩转python+人工智能-3》120,122节课深度优先疑问解答
深度优先(从左往右): 按照这个原则来:至于使用栈,或者队列:根据它们不同的特性:最终务必保证最终结果是原继承结构的“从左往右”:所以,如果是栈,就是右侧先入栈,左侧再入(这样左侧能先出来,遵循从左 ...
- [转][南京米联ZYNQ深入浅出]第二季更新完毕课程共计16节课
[南京米联]ZYNQ第二季更新完毕课程共计16节课 [第二季ZYNQ] ...
- SpringBoot常用Starter介绍和整合模板引擎Freemaker、thymeleaf 4节课
1.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-boot/doc ...
- centos mysql 实战 第一节课 安全加固 mysql安装
centos mysql 实战 第一节课 安全加固 mysql安装 percona名字的由来=consultation 顾问+performance 性能=per con a mysql ...
随机推荐
- excel中如何让每n行显示同一个数据
由于需要将数据按照下表格式存储,以方便读取展示,年份列需要每隔7行再递增1 方法: 1. 输入这个公式: = INT((ROW(E1)-1)/ 5)+ 1 进入一个空白单元格,您可以在其中填写序列号, ...
- 解决“找不到请求的 .Net Framework Data Provider。可能没有安装.”错误
问题: 这几天在装.NET 的开发环境,在装好VS2013和Oracle 11g之后,做了一个测试项目,运行调试没问题 但是涉及到数据库相关操作,如新建数据集.连接数据库等在调试的时候则会出现如下错误 ...
- django drf JWT
建议使用djangorestframework-jwt或者djangorestframework_simplejwt,文档为 https://github.com/GetBlimp/django-re ...
- Android 中 LayoutParams 的用法
一个控件应当使用它的父控件的 LayoutParams 类型.因此,一个 TableVow 应该使用 TableLayout.Params . 所以,以一个 TableRow 为例: TableRow ...
- C语言—第二次作业
1.本章学习内容 1.1思维导图 1.2本章学习体会即代码量学习体会 1.2.1学习体会 在本章中对循环的内容进行了加深训练,学习了一种解决问题的方法循环嵌套,也学到了伪代码的运用,在描述算法是运用伪 ...
- 【Oracle 12c】CUUG OCP认证071考试原题解析(30)
30.choose the best answer Examine the commands used to create DEPARTMENT_DETAILS and COURSE_DETAILS: ...
- P5282 【模板】快速阶乘算法(多项式运算+拉格朗日插值+倍增)
题面 传送门 前置芝士 优化后的\(MTT\)(四次\(FFT\)) 题解 这里有多点求值的做法然而被\(shadowice\)巨巨吊起来打了一顿,所以来学一下倍增 成功同时拿到本题最优解和最劣解-- ...
- [转] Cisco路由器DNS配置
禁用Web服务 Cisco路由器还在缺省情况下启用了Web服务,它是一个安全风险.如果你不打算使用它,最好将它关闭.举例如下: Router(config)# no ip http server 配置 ...
- Vim 中的持久撤消
Vim中的持久撤消 阅读文本大约需要俩分钟. 在 Vim 中像其他文本编辑器一样,你可以在当前会话中执行 "撤销/重做" .当一旦会话关闭,则你需要重新打开一个新文章,运行撤销将不 ...
- Markdown入门简介
参考 http://sspai.com/25137 作者: Te_Lee 文章来源: 少数派 Markdown入门简介(使用工具Haroopad) 一.使用的工具----haroopad(http:/ ...