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 ...
随机推荐
- (效果一)js实现上拉加载
实现思路:获取滚动元素的高度,滚动条距离顶部的距离,滚动条的高度, 算式:可视窗口的高度 + 滚动条距离顶部的距离 == 滚动条的高度就说明到底部. HTML <!doctype html> ...
- python学习之面向对象(下)
该篇主要是针对面向对象的细讲,包括类的多重继承,方法的重写,析构函数,回收机制进行讲解 #该类主要是讲述python面象对象的一些特征,包括继承,方法的重写,多态,垃圾回收 class person( ...
- 21天学通C++_Day3_Part3
控制程序流程 0.switch...case...语句中省略了break? break让程序能够退出switch结构,如果没有将继续评估后面的case语句 1.如何退出无限循环? 使用break退出当 ...
- HDU - 6183:Color it (线段树&动态开点||CDQ分治)
Do you like painting? Little D doesn't like painting, especially messy color paintings. Now Little B ...
- 【4】JDK和CGLIB生成动态代理类的区别
当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代理:事先写好代理对象类,在 ...
- FastAdmin 导出 Excel 相关资料收集 (2018-08-14)
FastAdmin 导出 Excel 相关资料收集 导出 Excel 文件时身份证号变成科学计数法怎么办? https://forum.fastadmin.net/thread/1346 姊妹篇 Fa ...
- bzoj 1499 [NOI2005]瑰丽华尔兹——单调队列优化dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1499 简单的单调队列优化dp.(然而当时却WA得不行.今天总算填了坑) 注意滚动数组赋初值应 ...
- Jython引用Java类
Ubuntu下如下指令安装Jython:$ sudo apt-get install jython下面的指令用于查看Jython版本:$ jython --version下面的代码是一个简单的Java ...
- linux下用户和组相关的文件及相关管理命令
1.用户信息文件 /etc/passwd 示例root:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2: ...
- Oracle LSNRCTL------监听器的启动和关闭
对于DBA来说,启动和关闭oracle监听器是很基础的任务,但是Linux系统管理员或者程序员有时也需要在开发数据库中做一些基本的DBA操作,因此了解一些基本的管理操作对他们来说很重要. 本文将讨论用 ...