幷查集

幷查集 

     在学习幷查集之前,先温习一下离散数学中学到的等价关系。

     若对于每一对元素(a,b),a,b∈S,aRb或者为true或者为false,则在集合S上定义关系(Relation)R。如果aRb是true,那么我们说a与b有关系。

     等价关系(equivalence relation)是满足下列三个性质的关系R:

     <1>、(自反性)对于所有的a∈S,aRa。

     <2>、(对称性)aRb当且仅当bRa。

     <3>、(传递性)若aRb且bRc,则aRc。

     等价类(equivalence class):一个元素a∈S的等价类是S的一个子集,它包含所有与a有关系的元素。等价类形成了对集合S的一个划分:S的每一个成员恰好出现在一个等价类中。

     幷查集就是指而言,就是解决给定元素a、b,判定a、b是否等价的问题,在实际应用中我们常常需要动态的维护等价关系,这就给判定元素是够等价的问题增加了难度。幷查集解释解决该问题的最优算法。

     下面介绍幷查集的基本操作:

 

//1、初始化操作 void Init(int n){ for(int i=1;i<=n;i++){ set[i]=i;//初始时定义集合i中有唯一元素i rank[i]=0;//rank[i]表是集合i的秩,幷查集按秩优先实现合并操作 } } //2、查找操作,返回元素r所在集合 int Find_set(int r){ if(set[r]-r) set[r]=Find_set(set[r]);//这个递归后赋值的操作是幷查集压缩路径的精要之处 return set[r]; } //3、合并操作,将x和y所在集合并在一个等价类(set的一个子集)中 void Union(int x,int y){ x=Find_set(x); y=Find_set(y);//这个很容易错写为x=set[x];y=set[y]; if(rank[x]>rank[y])//按秩优先合并 set[y]=x; else{ if(rank[x]==rank[y]) rank[y]++; set[x]=y; } } //注意:幷查集易错之处:要得到元素r所在的集合时, // 应该通过Find_set(r)来求解,直接输出set[r]是错误的! // 幷查集应用举例:无向图连通分量、无向图中环的存在性问题、Kruskal算法求最小生成树。  

你可能感兴趣的:(算法,Class)