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 ...
随机推荐
- 【MFC】MFC DLEdit 设计属于自己的编辑框_鼠标悬停
MFC DLEdit 设计属于自己的编辑框 2012-02-04 13:00 by 捣乱小子, 3543 阅读, 5 评论, 收藏, 编辑 起因 无意间看到了大牛们写的自定义编辑框控件,于是找了个时间 ...
- python库之threading
This module constructs higher-level threading interfaces on top of the lower level python库之_threadmo ...
- jstl中的用法
版权声明:本文为博主原创文章,未经博主允许不得转载. 在JSP的开发中,迭代是经常要使用到的操作.例如,逐行的显示查询的结果等.在早期的JSP中,通常使用Scriptlets来实现Iterator或者 ...
- [Luogu3538][POI2012]OKR-A Horrible Poem
luogu 题意 给出一个由小写英文字母组成的字符串\(S\),再给出\(q\)个询问,要求回答\(S\)某个子串的最短循环节. 如果字符串\(B\)是字符串\(A\)的循环节,那么\(A\)可以由\ ...
- Linux多网卡的时候执行机器Ip
在Linux部署的时候,经常会有多网卡的情况出现,这时候项目又需要指定Ip.在这种情况下,要配置linux机子的host,指定里头要使用的ip地址,否则linux机子不知道去找哪个ip. 一.查看本机 ...
- Nginx 改变错误日志打印级别
Nginx 改变错误日志打印级别 user root;worker_processes 2; worker_rlimit_nofile 10240;error_log logs/nginx_err ...
- c# HttpWebResponse 调用WebApi
public static class WebApiCaller { public static string HttpPost(string url, string body) { try { // ...
- 详细的nginx.conf中文资料整理
整理来源: https://blog.csdn.net/tjcyjd/article/details/50695922 整理结果 Nginx的配置文件nginx.conf配置详解如下: #Nginx用 ...
- Redis数据清除问题
Redis中数据清除可以分为两种方式 手动清除:指定要清除的key,通过delete命令即可清除 自动清除:使用Redis提供的数据过期策略 Redis数据过期策略 redis提供了非常灵活 ...
- java求10!的阶乘
package com.aaa; //求10!的阶乘 public class Cheng { public static void main(String[] args) { int s=1; fo ...