• 并查集


    查集就是维护了几个动态的集合,集合中的每一个元素都标记了一个父节点,同一个集合的代表是相同的。当一个元素的父节点就是他本身时,它就是该集合的代表。

    并查集有三种操作:

    1. init(n):用于初始化集合,将每个元素的父节点设置为他本身。即表示当前一个元素为一个集合,互相没有联系

    2. find(x):返回x所在集合的代表

    3. unite(x,y):合并x,和y所在的集合。即把y的代表设置为x所在集合的代表

    根据并查集判断两个元素是否有联系,只需判断他们是否在同一个集合里即可,也就是判断他们的代表是不是同一个

    >>初始化

    // 初始化n个元素
    void init(int n)
    {
        for (int i = 1; i <= n; i++) {
            par[i] = i;
            rank[i] = 0;
        }
    }

    >>查询

    //递归实现 
    int find(int x) 
    {  
        if (par[x]!=x) return find(par[x]);  
        else return x;
        //或者用return x == father[x] ? x: father[x] = find(father[x]);
    }
    
    //非递归路径压缩操作
    int find(int x)
    {
        int r = x;
        while(r!=par[r]) r = par[r];
        //路径压缩
        int i = x, j;        
        while(i!=r) {   
            j = par[i];   //用j暂存par[i]的父节点
            par[i] = r;   //par[i]指向根节点
            i = j;        //i移到父节点
        }
        return r;           
    }

    >>合并

    //合并x和y所在的集合
    void unite(int x, int y)
    {
        x = find(x);
        y = find(y); //将x和y的根分别赋值给x和y
        if (x==y) return; //如果x于y的根相同,则不必合并
     
        if (rank[x]<rank[y]) //合并时如果两棵树的高度不同,则将rank小的连到rank到的上面
            par[x] = y;
        else {
            par[y] = x;
            if (rank[x]==rank[y]) rank[x]++; //如果相同,则最高的高度合并之后需要在原来的基础上+1
        }
    }

     参考自:

    https://www.cnblogs.com/frankM/p/4399556.html

    https://www.cnblogs.com/52dxer/p/10470004.html

    https://www.cnblogs.com/sr1993/p/3697783.html

    http://www.cnblogs.com/tanhehe/archive/2013/01/28/2883506.html

    https://blog.csdn.net/zchahaha/article/details/51123557

  • 相关阅读:
    实验一 软件开发文档与工具的安装与使用
    ATM管理系统
    举例分析流程图与活动图的区别与联系
    四则运算
    机器学习 实验三
    机器学习 实验四
    机器视觉实验二
    实验三
    实验二
    实验一
  • 原文地址:https://www.cnblogs.com/wizarderror/p/10752791.html
Copyright © 2020-2023  润新知