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日

相关文章

  • 数据结构串的操作实例详解

    数据结构串的操作实例详解 什么是数据结构串? 数据结构串是由若干个字符按照一定的顺序排列而成的线性结构。可以对串进行许多操作,如子串的截取、串的连接、串的替换等等。 数据结构串的基本操作 串的初始化 为了操作一个串,我们需要先定义一个串并初始化,可以通过以下代码实现: #include <stdio.h> #define MAXSIZE 100 …

    数据结构 2023年5月17日
    00
  • 中国剩余定理(CRT)学习笔记

    约定 \(A\perp B\) 表示 \(\gcd(A,B)=1\)。 \(A\mid B\) 表示 \(B\equiv 0\pmod{A}(A\neq0)\)。 引入 考虑以下这道题: 有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。 問物幾何?—— 《孫子算經》 也就是说,求出下列关于 \(x\) 方程组的最小整数解: \[\begin{case…

    算法与数据结构 2023年4月30日
    00
  • JavaScript数据结构Number

    JavaScript数据结构Number 简介 JavaScript中的Number是一种表示数字的数据类型,包括整数和浮点数。Number类型的值是不可变的。 数字类型(Number)的创建 数字类型可以通过直接赋值的方式创建,如: let num = 10; // 整数 let floatNum = 3.14; // 浮点数 另外,JavaScript还…

    数据结构 2023年5月17日
    00
  • Lua中使用table实现的其它5种数据结构

    Lua中使用table可以实现多种数据结构,除了Lua原生支持的数组、哈希表之外,我们还可以用table来实现其他五种数据结构,这些数据结构包括集合(Set)、队列(Queue)、双端队列(deque)、堆栈(stack)以及链表(List)。 Set 集合数据结构中的元素是无序的、不重复的。使用table来实现集合数据结构,可以将元素作为table的key…

    数据结构 2023年5月17日
    00
  • Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)

    Java数据结构及算法实例:快速计算二进制数中1的个数 简介 本文将介绍在Java中快速计算二进制数中1的个数的算法。本算法是一种基于位运算的算法,其核心思想是利用位运算的快捷性,将原问题转化为每次计算一位是否为1的问题,使得计算速度大大提升。 背景知识 在理解本算法之前,需要了解Java中的一些背景知识: 1. 位运算 Java中的位运算符有如下几个: &…

    数据结构 2023年5月17日
    00
  • C语言实现带头结点的链表的创建、查找、插入、删除操作

    C语言实现带头结点的链表的创建、查找、插入、删除操作攻略 一、链表基本概念 链表是一种动态的数据结构,它可以在运行时动态地分配内存,支持数据的插入、删除等操作。链表(Linked List)由多个节点(Node)组成,每个节点包含两部分,一个是数据部分(Data),另一个是指向下一个节点的指针(Next)。 二、带头结点的链表 带头结点的链表是一种特殊的链表…

    数据结构 2023年5月17日
    00
  • Java数据结构与算法实现递归与回溯

    Java数据结构与算法实现递归与回溯攻略 什么是递归与回溯 递归是指函数调用自己的过程。在递归过程中,一般需要包含两个部分:递归调用过程和递归出口。递归应用广泛,例如在计算机科学中,递归可应用于算法设计中的分治思想和动态规划。 回溯是指在解决问题时,尝试每一种可能的分步方法,当尝试后发现该方法不行时,取消当前尝试的分步方法,回到上一步,再使用其他可能的分步方…

    数据结构 2023年5月17日
    00
  • Java数据结构之双端链表原理与实现方法

    Java数据结构之双端链表原理与实现方法 一、什么是双端链表? 双端链表是一种链式数据结构,它每个节点都有两个指针:一个指向前一个节点,一个指向后一个节点。它具有链表的所有特点,而且还有一些独特的优点:对于一个双向链表,我们可以从头到尾遍历,也可以从尾到头遍历。在某些情况下,它比单向链表更有用,因为它可以执行逆序遍历。 二、双端链表的原理 双端链表由节点构成…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部