c语言数据结构之并查集 总结

C语言数据结构之并查集总结

简介

并查集,也称作不相交集合,是一种树型的数据结构。并查集用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。

并查集只有两个操作:

  • find:确定某个元素属于哪个子集。它可以被用来确定两个元素是否属于同一子集。
  • union:将两个子集合并成同一个集合。

基本实现

以快速查找find和按秩合并rank为例:

const int MAXN = 1010;
int f[MAXN], rank[MAXN];

void makeSet(int n) {
    for(int i = 0; i <= n; i++) {
        f[i] = i;
        rank[i] = 0;
    }
}

int find(int x) {
    if(f[x] == x) {
        return x;
    } else {
        return f[x] = find(f[x]);
    }
}

void unionSet(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    if(fx == fy) {
        return;
    }
    if(rank[fx] < rank[fy]) {
        f[fx] = fy;
    } else {
        f[fy] = fx;
        if(rank[fx] == rank[fy]) {
            rank[fx]++;
        }
    }
}

应用示例

连通块数量

题目描述:

有一个n个点m条边的无向图,求连通块的数量。

根据题目可以建立一个n个元素的集合,每个元素代表一个点,首先将每个元素与自身合并,然后每遇到一条边,将两个点所在的集合合并,最后求并查集中不同簇的数目即为连通块的数量。

代码示例:

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    makeSet(n);
    while(m--) {
        int x, y;
        scanf("%d%d", &x, &y);
        unionSet(x, y);
    }
    int ans = 0;
    for(int i = 1; i <= n; i++) {
        if(f[i] == i) {
            ans++;
        }
    }
    printf("%d\n", ans);
    return 0;
}

判断是否为一棵树

题目描述:

给定一个无向图,判断它是否是一棵树。

根据树的定义,首先它必须是一个连通图,其次没有环,所以我们每遇到一条边,就要判断两个点是否已经在同一集合下,如果是,在操作这条边便产生了环。最后检查连通块数和边数是否符合树的要求即可。

代码示例:

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    makeSet(n);
    int cnt = 0;
    for(int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        if(find(x) != find(y)) {
            unionSet(x, y);
        } else {
            cnt++;
        }
    }
    if(cnt == 0 && n - 1 == m) {
        printf("YES\n");
    } else {
        printf("NO\n");
    }
    return 0;
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c语言数据结构之并查集 总结 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C语言数据结构与算法之排序总结(二)

    C语言数据结构与算法之排序总结(二) 本篇文章是关于C语言数据结构与算法中排序算法的详细讲解,涉及了八种排序算法。 冒泡排序(Bubble Sort) 冒泡排序是一种简单的排序算法。在排序过程中,它会重复地交换相邻的元素,这是它名称的由来。 示例代码: c void bubble_sort(int arr[], int n) { for (int i = 0…

    数据结构 2023年5月17日
    00
  • C++数据结构之双向链表

    C++数据结构之双向链表完整攻略 1. 什么是双向链表 双向链表是一种特殊的链表结构,每个节点拥有两个指针域,分别指向前继和后继节点。 双向链表不需要像单向链表那样从头到尾遍历整个链表,可以通过前后指针直接访问前后节点,提高了查找、删除、插入等操作的效率。 双向链表有一些常用的操作,如插入节点、删除节点、查找节点等。 2. 双向链表的实现 2.1 节点定义 …

    数据结构 2023年5月17日
    00
  • C语言线性表顺序存储结构实例详解

    C语言线性表顺序存储结构实例详解 线性表的定义 线性表是数据结构中最基本的结构之一。它们是由相同数据类型的一组数据元素组成的序列。线性表具有唯一的首元素和唯一的末元素,除第一个元素之外的每个元素都有唯一的前继,除最后一个元素之外的每个元素都有唯一的后继。 线性表的存储方式 线性表有两种存储方式: 顺序存储和链式存储。 顺序存储采用一段连续的内存空间来存储线性…

    数据结构 2023年5月17日
    00
  • Redis五种数据结构在JAVA中如何封装使用

    Redis 是一款高性能的键值存储数据库,支持五种不同的数据结构:字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。在Java中使用Redis需要封装对应的数据结构,本文将详细介绍如何封装Redis的五种数据结构。 封装Redis字符串数据结构 Redis字符串数据结构对应Java中的String类…

    数据结构 2023年5月17日
    00
  • C语言数据结构之串插入操作

    C语言数据结构之串插入操作 在C语言中,字符串是一种常见的数据类型,可以用字符数组来表示。当需要在字符串中插入新的字符时,就需要用到串插入操作。本文将详细讲解如何实现串插入操作。 串插入操作的实现 串插入操作的基本思路是:首先需要在插入位置后的字符串中腾出足够的空间,再把插入的内容拷贝到这个空间中。具体实现分以下步骤: 步骤1:计算需要插入位置的字符下标 需…

    数据结构 2023年5月17日
    00
  • 自学1

    Problem1 明明的随机数 ## 题目描述 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数 (N <= 100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“…

    算法与数据结构 2023年4月24日
    00
  • C语言中关于树和二叉树的相关概念

    C语言中关于树和二叉树的相关概念 树的概念 在计算机科学中,树是一种非常常见的数据结构,它由一组节点(通常称为元素)和一组连接节点的边组成。树是一种无向的、连通的、无环的图形结构,其中有一个节点被称为根节点,它没有父节点,而其他节点都有一个父节点。 树的定义很抽象,但在程序设计中,我们通常会使用一个节点类来实现树结构。一个节点类通常包含两个元素:一个是表示当…

    数据结构 2023年5月17日
    00
  • 【ACM算法竞赛日常训练】DAY5题解与分析【储物点的距离】【糖糖别胡说,我真的不是签到题目】| 前缀和 | 思维

    DAY5共2题: 储物点的距离(前缀和) 糖糖别胡说,我真的不是签到题目(multiset,思维) ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 原文链接(阅读原文获得更好阅读体验):https://www.eri…

    算法与数据结构 2023年4月18日
    00
合作推广
合作推广
分享本页
返回顶部