union_set

来源:互联网 发布:淘宝开店需要什么工具 编辑:程序博客网 时间:2024/06/06 23:18
#include<iostream>using namespace std;//开个数组放数据,如果par[i]>0说明i节点不是所在集合的根节点,par[i]存放的就是i节点的父节点,如果par[i]<0,说明i节点是所在集合的根节点,par[i]的值就是以i节点为根节点的集合的高度,用负数表示int par[10000];//查找根节点的函数find,查找到结果后顺便压缩下路径(坍塌规则),压缩路径是为了后面查找更快int find(int i){    //p用于存放找到的根节点    int p = i;    //查找过程    while (par[p] > 0)    {        p = par[p];    }    //路径压缩(坍塌规则)    while (i != p)    {        //保存当前节点的父节点        int next = par[i];        //把当前节点的父节点修改为根节点        par[i] = p;        //继续往上修改        i = next;    }    return p;}//合并过程,将a节点所在集合和b节点所在结合合并void unite(int a, int b){    //找到a节点所在集合的根节点    int pa = find(a);    //找到b节点所在集合的根节点    int pb = find(b);    //如果a节点的父节点和b节点的父节点一样,则不用合并    if (pa == pb)        return;    //如果a节点所在集合的高度和b节点所在集合的高度一样,则合并后新集合的高度要加1,自减是因为par数组中保存的是高度的负值    else if (par[pa] == par[pb])    {        par[pa]--;        par[pb] = pa;    }    //如果a节点所在集合的高度比b节点所在结合的高度大,则将b节点所在集合合并到a节点所在集合里面,合并后a节点所在集合高度不变    else if (par[pa] < par[pb])    {        par[pb] = pa;    }    else    {        par[pa] = pb;    }}//主函数初始化各种参数int main(){    //初始化par数组,每个节点一开始都是一个集合,并且都是所在集合的根节点,所以保存的是所在集合高度的负值-1    memset(par, -1, sizeof(par));    return 0;}
0 0