zoukankan      html  css  js  c++  java
  • 树-并查集-实现和应用

    并查集

    定义

    并查集是一种维护集合的数据结构,并:Union,查:Find,集:Set
    并查集支持下面两种操作:

    1. 合并:合并两个集合
    2. 查找:判断两个元素是否在一个集合

    并查集使用一个数组实现

    int father[N];
    

    其中 father[i] 代表元素 i 的父亲节点,而父亲节点本身也是这个集合内的元素。
    如果 father[i] == i 说明元素 i 是该集合的根结点,但是对于同一个结合来说只存在一个根结点,且将其作为所属集合的标识

    并查集的基本操作

    一个实现

    初始化father数组,但我们通常还会初始化另外一个辅助的数据结构 height[N], 来记录每个结点的深度,以使得我们的并查集的效率不会太差,不会生成一个非常长高的单链。

    初始化

    #define N 1001
    
    int father[N]; //记录父节点
    int height[N]; //记录每个节点的高度
    
    void Initial(int n)
    {
        for (int i = 0; i <= n; i++)
        {
            father[i] = i; // 初始化,父节点是自己
            height[i] = 0; // 高度为0
        }
    }
    

    查找

    由于同一个集合只存在一个根结点,所以查找操作就是对给定的结点寻找其根结点的过程。

    // 递归
    int Find(int x)
    {
        if (x != father[x])
        {
            x = Find(father[x]);
        }
        return x;
    }
    
    // 非递归
    int Find(int x)
    {
        while (x != father[x])
        {
            x = father[x];
        }
        return x;
    }
    

    合并

    把两个集合合并成一个,思路:

    1. 首先判断两个元素是否是同一个集合,就是看二者是否有相同的根结点
    2. 如果不是同一个集合,那么把一个集合的根结点的父亲指向另一个集合的根结点
      • 我们一般会将比较矮的集合(树)指向比较高的树
    void Union(int x, int y)
    {
        x = Find(x);
        y = Find(y);
        if (x != y)
        {
            if (height[x] < height[y])
            { // 矮树添加到高树上
                father[x] = y;
            }
            else if (height[x] > height[y])
            {
                father[y] = x;
            }
            else
            {
                father[y] = x;
                height[x]++;
            }
        }
    }
    
  • 相关阅读:
    java源码--Map
    数据结构 -- 哈希表(hash table)
    第三篇:SpringBoot模板Freemaker使用
    第四篇:SpringBoot 数据持久化之JdbcTemplate
    数据结构 -- 红黑树
    第二篇:彻底搞清楚 Spring Boot 的配置文件 properties和yml
    数据结构 -- AVL树
    Spring Boot之从Spring Framework装配掌握SpringBoot自动装配
    数据结构 -- Trie字典树
    数据结构 -- 并查集
  • 原文地址:https://www.cnblogs.com/veeupup/p/12551061.html
Copyright © 2011-2022 走看看