----------------------siwuxie095

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

基于 size 的优化

 
 

 
 


union( p , q ) 的时候,因为总是将第一个元素的根节点指向第二个元素

的根节点,就有可能让整棵树变的很高,导致
find( p ) 更耗时

 
 

 
 

解决方案:不应该固定的将一个元素的根节点指向另外一个元素的根节点,

而应该在做具体的指向操作之前,进行一下判断:判断两个元素所在集合

的元素总数谁大谁小

 
 

 
 

具体实现:存储每一个集合中元素的个数,在进行
Union 操作时,永远将

元素少的那组集合的根节点指向元素多的那组集合的根节点

 
 

这样一来,将会有更高概率形成一棵层数比较低的树

 
 

 
 

 
 

 
 

 
 

程序:基于
size 的优化

 
 

UnionFind.h:

 
 

#ifndef UNIONFIND_H

#define UNIONFIND_H

 
 

#include <cassert>

using namespace std;

 
 

 
 

 
 

//并查集:Quick Union + size

namespace UF

{

 
 

class UnionFind

{

 
 

private:

int* parent;

int* sz; // sz[i]表示以i为根的集合中元素个数

int count;

 
 

public:

UnionFind(int count)

{

this->count = count;

parent = new
int[count];

sz = new
int[count];

//在初始情况下,并查集里的元素,两两之间互不连接

for (int i = 0; i < count; i++)

{

parent[i] = i;

sz[i] = 1;

}

}

 
 

 
 

~UnionFind()

{

delete []parent;

delete []sz;

}

 
 

 
 

int find(int p)

{

assert(p >= 0 && p < count);

//不断追溯,直到p等于parent[p]

//即 p 为根节点,返回 p

//(返回的是根节点)

while (p != parent[p])

{

p = parent[p];

}

 
 

return p;

}

 
 

 
 

bool isConnected(int p, int q)

{

return find(p) == find(q);

}

 
 

 
 

void unionElements(int p, int q)

{

 
 

int pRoot = find(p);

int qRoot = find(q);

 
 

if (pRoot == qRoot)

{

return;

}

 
 

//size小的那棵树的根节点指向size大的那棵树的根节点

if (sz[pRoot] < sz[qRoot])

{

parent[pRoot] = qRoot;

sz[qRoot] += sz[pRoot];

}

else

{

parent[qRoot] = pRoot;

sz[pRoot] += sz[qRoot];

}

}

};

}

 
 

 
 

#endif

 
 

 
 

 
 

UnionFindTestHelper.h:

 
 

#ifndef UNIONFINDTESTHELPER_H

#define UNIONFINDTESTHELPER_H

 
 

#include
"UnionFind.h"

#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;

}

}

 
 

 
 

#endif

 
 

 
 

 
 

main.cpp:

 
 

#include
"UnionFindTestHelper.h"

#include <iostream>

using namespace std;

 
 

 
 

 
 

int main()

{

//规模是一百万

int n = 1000000;

 
 

UnionFindTestHelper::testUF(n);

 
 

system("pause");

return
0;

}

 
 

 
 

运行一览:

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

【made by siwuxie095】

基于size的优化的更多相关文章

  1. 基于rank的优化

    ------------------siwuxie095                                 基于 rank 的优化         基于 size 的优化,在大多数情况下 ...

  2. CBO 基于成本的优化器[基础]

    转载:CBO基于成本的优化器 ----------------------------------2013/10/02 CBO基于成本的优化器:让oracle获取所有执行计划的相关信息,通过对这些信息 ...

  3. Apache Spark 2.2中基于成本的优化器(CBO)(转载)

    Apache Spark 2.2最近引入了高级的基于成本的优化器框架用于收集并均衡不同的列数据的统计工作 (例如., 基(cardinality).唯一值的数量.空值.最大最小值.平均/最大长度,等等 ...

  4. 基于粒子群优化的无约束50维Rosenbrock函数求解

    基于粒子群优化的无约束50维Rosenbrock函数求解 一.问题重述 无约束50维的Rosenbrock函数可以描述如下: 其中, 0 要求按PSO算法思想设计一个该问题的求解算法. Rosenbr ...

  5. Spark SQL 性能优化再进一步:CBO 基于代价的优化

    摘要: 本文将介绍 CBO,它充分考虑了数据本身的特点(如大小.分布)以及操作算子的特点(中间结果集的分布及大小)及代价,从而更好的选择执行代价最小的物理执行计划,即 SparkPlan. Spark ...

  6. 基于Raft深度优化,腾讯云金融级消息队列CMQ高可靠算法详解

    背景介绍 分布式系统是指一组独立的计算机,通过网络协同工作的系统,客户端看来就如同单台机器在工作.随着互联网时代数据规模的爆发式增长,传统的单机系统在性能和可用性上已经无法胜任,分布式系统具有扩展性强 ...

  7. MySQL 并行复制演进及 MySQL 8.0 中基于 WriteSet 的优化

    MySQL 8.0 可以说是MySQL发展历史上里程碑式的一个版本,包括了多个重大更新,目前 Generally Available 版本已经已经发布,正式版本即将发布,在此将介绍8.0版本中引入的一 ...

  8. <强化学习>基于采样迭代优化agent

    前面介绍了三种采样求均值的算法 ——MC ——TD ——TD(lamda) 下面我们基于这几种方法来 迭代优化agent 传统的强化学习算法 || ν ν 已经知道完整MDP——使用价值函数V(s) ...

  9. 概述:基于事件的优化方法 / 事件驱动优化 / Event-Based Optimization / EBO

    大家好,我是月出 本文基于这篇综述,介绍了 事件驱动优化(Event-Based Optimization, EBO). 事件驱动优化,是一种建模现实场景.做优化的思路,理论和 MDP / 强化学习很 ...

随机推荐

  1. Centos 6.3 Realtek Audio Driver Compile

    /**************************************************************************** * Centos 6.3 Realtek A ...

  2. 查找对应jar的maven包

    当原有项目换成maven项目时,往往不知道具体jar包在maven里叫什么.这边文章教你如何去找到自己想要的jar的maven包. 工具/原料   浏览器 方法/步骤   1 登录一下网站 http: ...

  3. 20165222 预备作业3 Linux安装及学习

    一,安装Linux操作系统 一开始下载ubuntu的时候比较麻烦,然后用同学发给我的,才得以安装.根据教程,也没出现什么问题,只是下载的比较麻烦.  二,关于Linux的学习 1,Linux系统简介和 ...

  4. 给UIButton设置阴影及动画组

    //设置“开启旅程”按钮 UIButton *startBtn = self.startBtn; CGFloat btnW = ; CGFloat btnH = ; CGFloat btnX = (s ...

  5. java多线程:synchronized和lock比较浅析

    转载:http://www.toutiao.com/a6392135944652587266/?tt_from=weixin&utm_campaign=client_share&app ...

  6. 洛谷P3585 [POI2015]PIE

    传送门 题目大意:有个n*m的格子图,要求'x'点要被染成黑色 有个a*b的印章,'x'是可以染色的印章上的点. 要求用印章去染色格子 (1)印章不可以旋转. (2)不能把墨水印到纸外面. (3)纸上 ...

  7. kafka ksql && docker 安装试用

    备注: 使用docker 模式进行安装   1. 准备docker 环境(需要docker-compose)      docker 的安装不需要进行多描述了,直接yum 或者源码编译也可以     ...

  8. POI 单元格

    OI 单元格合并中的CellRangeAddress 参数: CellRangeAddress(int, int, int, int) 参数:起始行号,终止行号, 起始列号,终止列号 sheet.ad ...

  9. Oracle配置文件tnsnames.ora新增链接后连接报错:ORA-12154: TNS:无法解析指定的标识符

    一个空格引发的血案:在tnsnames. ora文件中新加了一个配置,该配置估计当时是拷的别人的直接粘贴上去的,然后发现用pl/sql连接就一直报错了,后面排除了用户名和密码问题和后,仔细看了该文件才 ...

  10. WinForm Flicker闪屏解决方案

    开发WinForm 程序时经常会遇到闪屏的问题,这会给用户造成很差的使用体验,所以必须妥善解决好这个问题. 首先,我们先要找出闪屏的原因,就我目前遇到的问题而言,其原因真是五花八门. 主要的原因有:使 ...