并查集C语言

北战南征 提交于 2020-01-23 22:22:26

并查集

什么是并查集

并查集是用来处理“有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中”的问题的。通常我们使用的数据结构空间复杂度还可以但时间复杂度远远超出我们所需求的。而并查集这种树状数据结构正好可以处理这种一些不相交集合的合并及查询问题,大大减少了我们的时间复杂度。
简单的来说就是一个把自己的根列出来,然后再查找自己的根的在哪的问题。

怎么实现并查集

首先并查集有三各要素需要明确:根,树枝,查找路径。悬空说很难落实下面我们引入例题:
在这里插入图片描述

这是一道很明显的并查集的题目,我们先将每个人认识的头目(根)列到root数组中去,然后我们通过判断他们的根是否一致来实现计算其数量也就是我们说的查找路径
下面是代码实现:

int search(int men)
{
    int now;
    now=men;
    while(root[men]!=men)
    {
        men=root[men];
    }//查找根
    if(now!=men)
    {
        root[now]=root[men];
    }//压缩路径
    return men;
}

我们通过压缩路径来减少下次判断的时间,然后我们只要再对根的一致进行判断就行了。下面是总代码的实现:

#include <stdio.h>
#include <stdlib.h>
int root[100010];
int search(int men)
{
    int now;now=men;
    while(root[men]!=men)
    {
        men=root[men];
    }
    if(now!=men)
    {
        root[now]=root[men];
    }
    return men;
}
int main()
{
    int n,m,num,i;
    scanf("%d%d",&n,&m);
    num=0;
    for(i=0;i<n;i++)
        root[i]=i;
    for(i=0; i<m; i++)
    {
        int men1,men2,root1,root2;
        scanf("%d%d",&men1,&men2);
        root1=search(men1);
        root2=search(men2);
        if(root1!=root2)
        {
            root[men1]=men2;
        }
    }
    for(i=0;i<n;i++)
        if(root[i]==i)
        num++;
    printf("%d",num);
}

这只是最简单的并查集的实现,我们还可以通过并查集来对树的头进行链接来实现森林的构造。(鄙人知识浅薄尚未对其进行深入探讨),如有错误希望大神指正。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!