并查集

概念

并查集是用来管理元素分组情况的数据结构.并查集有两个功能:1.查询a,b是否在同一分组 2.合并a,b为同一分组.并查集可以高效执行这两个功能.对于n个元素的并查集操作,平均复杂度小于(log(n)).

实现

并查集的结构是树状结构,并查集的核心是par[]数组,par[i]表示连接第i个点的前一个点,初始化par[i]=i,查询根结点时只需沿着par[i]一直找直到找到par[x]=x即可,此时x即为i的根结点.合并x,y时直接让par[x的根结点]=y的结点即可.由于可能发生树的退化,导致复杂度变高,所以需要优化.优化包括两个内容,(1)建立数组rank[]表示树的高度,合并时将高度低的树连上高度高的树,举个例子,假设a结点的根结点为x,b结点的根结点为y.rank[x]<rank[y],则par[x]=y,rank[]初始化为0.(2)路径压缩,例如1-2-3-4-5可以压缩成,1-2,1-3,1-4,1-5.这里路径压缩时尽管树的高度会发生变化,但为了第一个优化能进行,可以忽略这个变化,也就是路径压缩时树的高度不修改.

代码

 1 int par[MAX];
 2 int rank[MAX];
 3 
 4 void init(int n) //初始化需要根据题目的需求更改 
 5 {
 6     for(int i=0;i<n;i++)
 7     par[i]=i;
 8     return ;
 9 }
10 
11 int find(int x)
12 {
13     if(par[x]==x) return x;
14     else return par[x]=find(par[x]); //路径压缩 
15 }
16 
17 void unite(int x,int y)
18 {
19     x=find(x),y=find(y);
20     if(x==y) return ;
21     if(rank[x]<rank[y]) par[x]=y;
22     else
23     {
24         par[y]=x;
25         if(rank[x]==rank[y]) rank[x]++; //两颗同高度树连起来时会使树高度+1 
26     }
27     return ;
28 }

 

posted @ 2019-04-15 14:30  VBL  阅读(150)  评论(0编辑  收藏  举报