Quick Find
--------------------siwuxie095
Quick Find
这里介绍并查集的一种实现思路:Quick Find
对于一组数据,并查集主要支持两个操作:
(1)union( p , q ),即 并,将 p 和 q 两个元素合并在一起,也就是所谓的连接
(2)find( p ),即 查,查找 p 元素具体在哪个集合中
有了这两个操作,使用并查集也可以轻易地回答这样一个问题:
isConnected( p , q ),传入 p 和 q 两个元素,判断两个元素是否相连接
并查集的基本数据表示
对于如上需求,最简单的数据表示方式就是数组,其中:数组的索引
用来表示元素
如果有 0-9,共 10 个元素,这些元素之间连接关系的表示方法如下:
「即
给每一个元素都赋上一个值」
(1)
0-4 对应的值都是 0,而 5-9 对应的值都是 1。表示 0-4 这 5 个
元素之间是互相连接的,而 5-9 这 5 个元素之间是互相连接的
(2)
0、2、4、6、8 对应的值都是 0,而 1、3、5、7、9 对应的值都
是 1。表示 5 个偶数和 5 个奇数是分别互相连接的
不妨给这个数组起一个名字,叫做 id,即 所有连接在一起的元素,
它们都具有相同的
id
程序:Quick Find 的实现
UnionFind.h:
#ifndef UNIONFIND_H #define UNIONFIND_H #include <iostream> #include <cassert> using namespace std; //并查集:Quick Find namespace UF { class UnionFind { private: int *id; int count; public: UnionFind(int count) { this->count = count; id = new //在初始情况下,并查集里的元素,两两之间互不连接 for (int i = 0; i < count; i++) { id[i] = i; } } ~UnionFind() { delete []id; } //找到每一个元素所集合的id:直接访问id相应的值即可 //称这种实现为 Quick Find,也就是Find操作非常快, //只需要使用O(1)的时间复杂度就够了 int find(int p) { assert(p >= 0 && p < count); return id[p]; } //回答两个元素是否相互连接的问题:id相同则相互连接 bool isConnected(int p, int q) { return find(p) == find(q); } //Quick Find下的Union操作的时间复杂度 O(n) //(因为union在C++中是关键字,所以不能把函 //数名起成union) void unionElements(int p, int q) { int pID = find(p); int qID = find(q); if (pID == qID) { return; } //Union操作是将两个元素所在集合全部并在一起,而不是只将 p 元素 //并到 q 元素所在集合,或只将 q 元素并到 p 元素所在集合 // //这样,本来两个元素所在集合的所有元素,两两之间就互相连接了 for (int i = 0; i < count; i++) { //或者反向亦可 if (id[i] == pID) { id[i] = qID; } } } }; } #endif |
UnionFindTestHelper.h:
#ifndef UNIONFINDTESTHELPER_H #define UNIONFINDTESTHELPER_H #include #include <iostream> #include <ctime> using namespace std; namespace UnionFindTestHelper { void testUF(int n) { //设置随机种子 srand(time(NULL)); UF::UnionFind uf = UF::UnionFind(n); time_t startTime = clock(); //先进行n次的并,即 Union 操作 for (int i = 0; i < n; i++) { int a = rand() % n; int b = rand() % n; uf.unionElements(a, b); } //再进行n次的查,即 Find 操作 for (int i = 0; i < n; i++) { int a = rand() % n; int b = rand() % n; uf.isConnected(a, b); } time_t endTime = clock(); //打印2*n个操作耗费的时间 cout << "UF, " << 2 * n << " ops, " << double(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl; } } //由于单个Union操作的时间复杂度是O(n)级别的,所以执行n次Union操作, //时间复杂度就是O(n^2)级别的 // //而在查看是否连接isConnected()的复杂度是O(1),执行n个操作,就是O(n) // //不过整体上,此次测试的复杂度是O(n^2)级别的 // //即 Quick Find,它查找(Find)的速度非常快,可是在执行并(Union)这个 //操作的时候,效率却不尽人意 #endif |
main.cpp:
#include #include <iostream> using namespace std; int main() { //规模是十万 int n = 100000; UnionFindTestHelper::testUF(n); system("pause"); return } |
运行一览:
【made by siwuxie095】
Quick Find的更多相关文章
- [算法]——快速排序(Quick Sort)
顾名思义,快速排序(quick sort)速度十分快,时间复杂度为O(nlogn).虽然从此角度讲,也有很多排序算法如归并排序.堆排序甚至希尔排序等,都能达到如此快速,但是快速排序使用更加广泛,以至于 ...
- Quick Cocos (2.2.5plus)CoinFlip解析(MenuScene display AdBar二次封装)
转载自:http://cn.cocos2d-x.org/tutorial/show?id=1621 从Samples中找到CoinFlip文件夹,复制其中的 res 和 script 文件夹覆盖新建工 ...
- 《Qt Quick 4小时入门》学习笔记4
http://edu.csdn.net/course/detail/1042/14806?auto_start=1 Qt Quick 4小时入门 第七章:处理鼠标与键盘事件 1.处理鼠标事件 鼠标信号 ...
- 《Qt Quick 4小时入门》学习笔记3
http://edu.csdn.net/course/detail/1042/14807?auto_start=1 Qt Quick 4小时入门 第八章:Qt Quick中的锚(anchors)布局 ...
- 《Qt Quick 4小时入门》学习笔记2
http://edu.csdn.net/course/detail/1042/14805?auto_start=1 Qt Quick 4小时入门 第五章:Qt Quick基本界面元素介绍 1. ...
- spring in action 4th --- quick start
读spring in action. 环境搭建 quick-start依赖注入 面向切面 1.环境搭建 jdk1.8 gradle 2.12 Intelij idea 2016.2.1 1.1创建一个 ...
- A Quick Introduction to Linux Policy Routing
A Quick Introduction to Linux Policy Routing 29 May 2013 In this post, I’m going to introduce you to ...
- Quick Apps for Sharepoint小型BI解决方案
Quick Apps for Sharepoint介绍 Quick Apps for Sharepoint前身是Quest Webpart ,由企业软件开发商QuestSoftware开发,Quest ...
- Sharepoint + Office Infopart + Quick Apps for Sharepoint搭建无纸化工作平台
项目背景: 某大型外企各分部通过互联网专线统一域环境,Exchange邮件系统,Sharepoint平台及依赖环境已经购买并搭建起来,Dell Quick app for Sharepoint已购卖并 ...
- cocos2d-x quick 学习 二 Hello world
总算找到问题了. 这几天一直在招问题没有找到原因. 为什么按照文档就不能建立新的项目. 不能建立自己的 hello world 我之前下载的源码文件 quick-cocos2d-x-2.2.5 ...
随机推荐
- C 时间函数总结
头文件 time.h 处理器时间函数 clock_t clock(void) 处理器的处理时间,如可以在 main开始的地方 使用这个函数,然后再 完毕后 调用这个函数 并 减去 之前的返回值,为了 ...
- ubuntu 添加新硬盘
查看硬盘: # fdisk -l ... Disk /dev/sdb: 274.9 GB, 274877906944 bytes 255 heads, 63 sectors/track, 33418 ...
- node.js之npm库
npm库安装可分为本地安装和全局安装,本地安装如下: npm install <Module name> 但是好像会出问题,官方貌似推荐全局安装,so 全局安装官方所给命令如下: npm ...
- Microsoft office2007免费版下载(安装 + 破解)
office2007官方下载 免费完整版是微软推出的办公软件,office2007使用方法很简单,解压软件之后,运行“setup.exe”之后按照提示点击下一步,输入产品秘钥,就可以正常安装了.Mic ...
- Bootstrap-table学习笔记(二)——前后端分页模糊查询
在使用过程中,一边看文档一边做,遇到了一些困难的地方,在此记录一下,顺便做个总结: 1,前端分页 2,后端分页 3,模糊查询 前端分页相当简单,在我添加了2w条测试数据的时候打开的很流畅,没有卡顿. ...
- 【eclipse】 怎么解决java.lang.NoClassDefFoundError错误
前言 在日常Java开 发中,我们经常碰到java.lang.NoClassDefFoundError这样的错误,需要花费很多时间去找错误的原因,具体是哪个类不见了?类 明明还在,为什么找不到?而且我 ...
- C#动态执行代码
在开始之前,先熟悉几个类及部分属性.方法:CSharpCodeProvider.ICodeCompiler.CompilerParameters.CompilerResults.Assem ...
- Ctrl+H 浪潮Raid配置文档
说明 本手册适用于LSI芯片Raid卡 包括但不限于Inspur 2008/2108 Raid卡.LSI 9240/9260/9261/9271 等Raid卡. 不同型号的Raid卡在某些功能上的支持 ...
- Oracle cursor_sharing 参数 详解
一. 官网的说明 http://download.oracle.com/docs/cd/E11882_01/server.112/e17110/initparams042.htm#REFRN10025 ...
- php调试时echo,print_r(),var_dump()的区别
简单说: var_dump() 能打印出类型 print_r() 只能打出值echo() 是正常输出... 需要精确调试的时候用 var_dump();一般查看的时候用 print_r() 另外 , ...