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 ...
随机推荐
- 使用iptables nat进行端口转发
1.将发向HostA:PortA的请求转发到HostB:PortB iptables -t nat -A PREROUTING -p tcp -i eth0 -d HostA --dport Port ...
- HDU - 5297:Y sequence (迭代&容斥)
Yellowstar likes integers so much that he listed all positive integers in ascending order,but he hat ...
- java多线程:线程体往外抛出异常的处理机制实践
1当线程的线程体内部无捕获异常,将异常抛出线程体外,不同情况下,程序处理机制 测试类 package com.ehking.bankchannel.domesticremit.facade.impl; ...
- Spring和MyBatis整合
前言:在前面一篇文章中,介绍了单独使用MyBatis连接orace的例子,在这里分享学习下Spring和MyBatis是如何整合的,以具体工程为例子 阅读目录: 1.环境准备 2.搭建工程 2.1.a ...
- 十九、python沉淀之路--装饰器
一.实现装饰器的预备知识 装饰器 = 高阶函数 + 函数嵌套 + 闭包 1.高价函数定义: 1.函数接收的参数是一个函数名 2.函数的返回值是一个函数名 3.满足上述条件任意一个,都可称之 ...
- 【Spring】Junit加载Spring容器作单元测试(整理)
[Spring]Junit加载Spring容器作单元测试 阅读目录 >引入相关Jar包 > 配置文件加载方式 > 原始的用法 > 常见的用法 > 引入相关Jar包 一.均 ...
- Android蓝牙UUID简要
UUID是"Universally Unique Identifier"的简称,通用唯一识别码的意思.对于蓝牙设备,每个服务都有通用.独立.唯一的UUID与之对应.也就是说,在同一 ...
- eclipse怎么在项目里面批量替换单词
先选中你要替换的东东,然后再菜单栏中找到Search→Text→Project(先创建要搜索的project),这样就会在整个项目中查找单词.然后在Search的Console中,单击项目,右键选择R ...
- ror配置unicorn部署
unicorn是目前在ror上比较流行的应用服务器,配合nginx用来直接部署rails程序,下面这种方式应该是共享socket,不断fork子进程,有点类似php-fpm的模式 安装unicorn ...
- 分布式缓存系统 Memcached 哈希表操作
memcached 中有两张hash 表,一个是“主hash 表”(primary_hashtable),另外一个是“原hash 表”(old_hashtable).一般情况下都在主表中接受操作,在插 ...