• 数据结构——并查集


    一、认识并查集

    并查集,逻辑上是一种集合,能够快速的实现合并和查询,因此得名。这里的查询指的是判断两个元素是否在同一集合。并查集能够高效地管理元素分组情况,为程序设计提供极大的便利。

    并查集的本质是树形结构,属于同一集合的元素会位于同一颗树中。由于树的度和深度都不受任何限制,非常自由,我们可以很容易地实现合并查询等基本操作。

    二、并查集的基本操作及实现

    并查集中的元素除了自己本来带有的属性外,还应有带有两个值来表示其在并查集中的状态:father 这个结点的父节点的索引。

    1.初始化

    在初始的时候,所有的结点互相之间都没有关系,呈现森林的状态。此时,所有结点都是自己的根结点,所有树的高度都是1(只有一个元素)。

    int father[maxn];//父节点的索引
    
    void init(int N)//从1开始初始化N个结点
    {
        for(int i = 1;i <= N;i++)
        {
            father[i] = i;
        }
    }

    2.查询

    查询两个元素是否在同一集合中,只需要查询他们的根结点是否相同就可以了。而查找根结点可以通过递归快速地实现:

    int find(int x)//查询编号为x的结点的根结点
    {
        if(father[x] == x)
            return x;
        else
            return find(father[x]);
    }

    路径压缩:如果合并的算法不够好的话,并查集可能会出现树的度接近甚至等于树的结点个数的极端情况,也就是退化。如下图,如果后面的结点继续这样连接下去的话,查询的复杂度会变得非常高。

    如果一个结点的父结点是谁并不重要的话,我们可以在查询到这个结点的根结点时直接将它连到根结点,这样,下一次查询就只需要一步,可以有效地避免退化。

    如图:

    int find(int x)//查询编号为x的结点的根结点
    {
        if(father[x] == x)
            return x;
        else
            return father[x] = find(father[x]);//路径压缩
            //return find(father[x]);
    }

    3.合并

    合并两个集合,只需要找出两棵树的根结点,再把其中的某一个连接到另一个就可以了。

    void unite(int x, int y)//合并x和y所在的集合
    {
        x = find(x);
        y = find(y);
        if(x == y)//如果x和y已在同一集合,那就打扰了
            return;
        father[x] = y;
    }
  • 相关阅读:
    python学习笔记(7)
    python学习笔记(6)
    python学习笔记(5)
    python学习笔记(4)
    python学习笔记(3)
    python学习笔记(2)
    软件工程结对编程第二次作业
    软件工程结对编程第一次作业
    软件工程第三次作业
    答编辑问
  • 原文地址:https://www.cnblogs.com/sun-of-Ice/p/9433449.html
Copyright © 2020-2023  润新知