并查集(union/find)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集(union/find)相关的知识,希望对你有一定的参考价值。
在计算机科学中,并查集是一种树型的数据结构,其保持着用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。有一个联合-查找算法(union-find algorithm)定义了两个操作用于此数据结构:
Find:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。
Union:将两个子集合并成同一个集合。
因为它支持这两种操作,一个不相交集也常被称为联合-查找数据结构(union-find data structure)或合并-查找集合(merge-find set)。
为了更加精确的定义这些方法,需要定义如何表示集合。一种常用的策略是为每个集合选定一个固定的元素,称为代表,以表示整个集合。接着。Find(x)返回x所属集合的代表,而Union使用两个集合的代表作为参数。(取自维基百科)
开始时的状态:
(摘自数据结构与算法分析 Java语言描述第二版)
即定义:
for(int i=0;i<n;i++) id[i]=-1;
以下为具体实现:
class unionfind { private int count; private int[] id; public union(int n) { count=n; id=new id[n]; for(int i=0;i<n;i++) id[]=-1; } public int count() { return count; } public boolean connected(int p,int q) { return find(p)==find(q); } private int find(int n) { while(p!=id[p]) p=id[p]; return p; } public void union(int p.int q) //按大小union { int proot=find(p); int qroot=find(q); if(proot==qroot) return; id[proot]=qroot; count--; } }
优化方式 按高度union
for(inti=0;i<n;i++) sz[i]=1; public void union(int p,int q) //按高度union { int proot=find(p); int qroot=find(q); if (sz[proot<sz[qroot]]) { id[proot]=qroot; sz[qroot]+=sz[proot]; } else { id[qroot]=proot; sz[proot]+=sz[qroot]; count--; } }
路径压缩
private int find(int n) //路径压缩 { while(n!=id[n]) n=id[id[n]]; return n; }
以上是关于并查集(union/find)的主要内容,如果未能解决你的问题,请参考以下文章