并查集——路径压缩
2017-09-25 11:11
253 查看
关于Rank的优化
上文中我们已经对代码进行了几次优化,使得进行连接操作的时候,所形成的树长度尽量短,但同时也存在另一种情况:集合元素多,但是每个元素分别指向根节点,这样就只有两层(举例),那么就应该把这棵树的根节点指向另一棵高树的根节点,就出现了所谓的“集合元素多,但是树长度短“的情况,因此,应当首先考虑树的高度,而非树的元素量。
进行如下优化:
路径压缩(Path Compression)
注意:递归会耗费一定时间,视情况选择路径压缩的程度。此种路径压缩完毕后,形成的是一棵高度为2的树,每个元素指向根节点。
相应地,也有一种不太彻底的路径压缩方法:
并查集的时间复杂度近乎为O(1)
上文中我们已经对代码进行了几次优化,使得进行连接操作的时候,所形成的树长度尽量短,但同时也存在另一种情况:集合元素多,但是每个元素分别指向根节点,这样就只有两层(举例),那么就应该把这棵树的根节点指向另一棵高树的根节点,就出现了所谓的“集合元素多,但是树长度短“的情况,因此,应当首先考虑树的高度,而非树的元素量。
进行如下优化:
class unionFind{ private: int* parent; int* rank; //记录树的高度 int count; public: UnionFind(int count){ parent=new int[count]; rank=new int[count]; this->count=count; for(int i=0;i<count;i++){ parent[i]=i; rank[i]=1; //初始高度都为1 } } ~unionFind(){ delete [] parent; delete [] rank; } int find(int p){ assert(p>=0&&p<count); 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; if(rank[pRoot]<rank[qRoot]){ //两棵树一高一低,连接后高度与高树保持一致 parent[pRoot]=qRoot; } if(rank[pRoot]>rank[qRoot]){ parent[qRoot]=pRoot; } else{ //两棵树高度一样,连接后高度加一 parent[qRoot]=pRoot; rank[qRoot]++; } } };
路径压缩(Path Compression)
int find(int p){ if(p!=parent[p]) parent[p]=find(parent[p]); return parent[p]; }
注意:递归会耗费一定时间,视情况选择路径压缩的程度。此种路径压缩完毕后,形成的是一棵高度为2的树,每个元素指向根节点。
相应地,也有一种不太彻底的路径压缩方法:
int find(int p){ assert(p>=0&&p<count); while(p!=parent[p]){ parent[p]=parent[parent[p]]; p=parent[p]; } return p; }
并查集的时间复杂度近乎为O(1)
相关文章推荐
- 好朋友(并查集与路径压缩的结合体)
- 算法训练 安慰奶牛 (并查集—路径压缩、Kruskal算法)
- 并查集 路径压缩
- poj.1988并查集-路径压缩、更新结点(偏移量)
- 并查集算法和路径压缩
- 并查集 + 路径压缩(经典) UVALive 3027 Corporative Network
- Corporative Network UVA - 1329 加权并查集(压缩路径优化)
- uva1329 Corporative Network(并查集:路径压缩)
- 并查集(2)-按秩合并和路径压缩
- 并查集实现-(秩优化+路径压缩+java)
- 并查集。路径压缩 算法运用学习(一)
- 并查集 路径压缩(具体解释)
- HDOJ 3635 并查集- 路径压缩,带秩合并
- BZOJ 3674 可持久化并查集加强版(路径压缩版本)
- 并查集 路径压缩
- 并查集 ---压缩路径
- 并查集的路径压缩
- 并查集算法和路径压缩
- 并查集 路径压缩 非递归写法
- 【模板】【数据结构】并查集(路径压缩+按秩合并)