并查集

来源:互联网 发布:线割编程招聘 编辑:程序博客网 时间:2024/04/26 07:29

并查集,是对不相交集合的合并查找。

主要步骤

1, 合并不相交集合

2, 判断两个集合是否有相同的根

3, 优化:路径压缩

模板

1,初始化

初始化father:各个节点独立成树,并且其father[i]=i,也就是其父节点就是其自身;
初始化rank:各个节点为根节点,所以高度都为1,rank[i]=1。
2,查找

find_set(x)   判断两个集合是否同根。

3合并

 Union(x,y)输入元素x和y来自两个不相交的集合,找到其最原始的父亲节点,并将一个原始父亲节点设置为另一个原始父亲节点的父亲节点

主要代码

//初始化#define N 100int father[N],rank[N];void union_set() {    for(int i=0; i<N; i++)     {  father[i] = i;     rank[i]=1;     } }//查找int find (int x){if (x!=father([x])father(x)=find (father[x])return father[x];}//合并void Union (int x,int y){x=find(x);y=find(y);    if (x == y) return;    if (rank[x] > rank[y])     {        father[y] = x;    }    else    {        if (rank[x] == rank[y])        {            rank[y]++;        }        father[x] = y;    }}/*    按秩合并x,y所在的集合(即按照树形的高度,将高度低的合并到高的里面去)   实时更新秩。*///查找时路径压缩采用的是递归,可能会造成溢出栈//以下是非递归的路径压缩(较完美)int find(int x){    int k, j, r;    r = x;    while(r != parent[r])     //查找跟节点        r = parent[r];      //找到跟节点,用r记录下    k = x;            while(k != r)             //非递归路径压缩操作    {        j = parent[k];         //用j暂存parent[k]的父节点        parent[k] = r;        //parent[x]指向跟节点        k = j;                    //k移到父节点    }    return r;         //返回根节点的值            }






0 0
原创粉丝点击