算法代码实现之Union-Find,C++实现,quick-find、quick-union、加权quick-union(附带路径压缩优化)
2016-02-29 09:49
771 查看
本算法主要解决动态连通性一类问题,这里尽量用精炼简洁的话来阐述。
数据结构描述:
有N个节点(索引0~N-1),可以查询节点数量
可以连接两个节点
可以查询两个节点是否连通
算法大致设计思路:
每个节点初始化为不同的整数标记
通过一个辅助函数查询某个节点的标记值
如果两节点标记相同,说明两节点是连通的
抽象基类:
标记相同的节点是连通的
查询根节点的时候顺便将该节点的父节点直接指向根节点,压缩路径
数据结构描述:
有N个节点(索引0~N-1),可以查询节点数量
可以连接两个节点
可以查询两个节点是否连通
算法大致设计思路:
每个节点初始化为不同的整数标记
通过一个辅助函数查询某个节点的标记值
如果两节点标记相同,说明两节点是连通的
抽象基类:
class UnionFind { public: UnionFind(int n); ~UnionFind(); int Count(); virtual bool Connected(int p,int q)=0; virtual void Union(int p,int q)=0; protected: int *id; int sz; int num; }; UnionFind::UnionFind(int n) { this->num = this->sz = n; this->id = new int ; for(int i=0; i<n; i++) { this->id[i] = i; } }; UnionFind::~UnionFind() { delete this->id; delete &this->num; delete &this->sz; }; int UnionFind::Count() { return this->num; };
QuickFind:
a和b进行union的时候,将b及与b连通节点的标记都置为和a的标记一样标记相同的节点是连通的
class QuickFind : public UnionFind { public: QuickFind(int n); bool Connected(int p,int q); void Union(int p,int q); }; QuickFind::QuickFind(int n):UnionFind(n) {}; bool QuickFind::Connected(int p,int q) { return this->id[p] == this->id[q]; }; void QuickFind::Union(int p,int q) { int k = this->id[q]; for(int i=0; i<this->sz; i++) { if(this->id[i]==k) { this->id[i]=this->id[p]; } } this->num--; };
QuickUnion:
连通的节点形成一棵树,根节点相同class QuickUnion : public UnionFind { public: QuickUnion(int n); bool Connected(int p,int q); void Union(int p,int q); protected: int findRoot(int p); }; QuickUnion::QuickUnion(int n):UnionFind(n) {}; int QuickUnion::findRoot(int p) { while(p!=this->id[p]) { p = this->id[p]; } return p; }; bool QuickUnion::Connected(int p,int q) { return this->findRoot(p)==this->findRoot(q); }; void QuickUnion::Union(int p,int q) { int i = this->findRoot(p); int j = this->findRoot(q); if (i == j) { return; } this->id[j] = this->id[i]; this->num--; };
加权QuickUnion(附带路径压缩优化):
union的时候小树挂在大树下查询根节点的时候顺便将该节点的父节点直接指向根节点,压缩路径
class WeightedQuickUnion : public QuickUnion { public: WeightedQuickUnion(int n); ~WeightedQuickUnion(); void Union(int p,int q); protected: int findRoot(int p); private: int *sz; }; WeightedQuickUnion::WeightedQuickUnion(int n):QuickUnion(n) { this->sz = new int ; for(int i=0; i<n; i++) { this->sz[i] = 1; } }; WeightedQuickUnion::~WeightedQuickUnion() { delete this->sz; }; int WeightedQuickUnion::findRoot(int p) { while (p != this->id[p]) { this->id[p] = this->id[this->id[p]]; p = this->id[p]; } return p; }; void WeightedQuickUnion::Union(int p,int q) { int i = this->findRoot(p); int j = this->findRoot(q); if (i == j) { return; } if (this->sz[i] < this->sz[j]) { this->id[i] = j; this->sz[j] += this->sz[i]; } else { this->id[j] = i; this->sz[i] += this->sz[j]; } this->num--; };
相关文章推荐
- vs2010 C++创建和使用动态链接库(dll)
- C++语言-05-三大特性
- C语言_数组与排序
- C语言_循环语句
- C++ Super-FAQ 『Deconstructor』
- C语言_运算符的优先级
- [c++]win下utf8源文件编译运行后乱码,codeblocks编辑器
- C++编写安全OCX,IE不弹出安全提示
- c++在VS2010编译的程序在XP系统托盘气泡提示不成功解决办法
- C/C++: short , int , long , long long数据类型选用
- C++多态性理解
- C++多线程操作(火车售票系统线程同步)
- c++中信息隐藏的实现
- c/c++ (void) var语句的作用与ignore_unused的对比
- c++面试笔试集锦
- list和vector的区别
- C++多线程socket系统新编
- USACO Dual Pal 4000 indromes 解题日志
- 从C++转向java——5、数组
- c语言编程中%g是什么格式