C语言并查集的非递归实现详解

 更新时间:2021年09月07日 11:30:28   作者:hnjzsyjyj  
以下是对C语言并查集的递归实现与非递归实现代码进行了详细的介绍,需要的朋友可以过来参考下,希望能够给你带来帮助

【算法分析】

经典的递归实现的并查集,在数据规模过大时,可能会爆栈,因此有了并查集的非递归实现。核心代码如下:

int find(int x) {
	int t=x;
	while(t!=pre[t]) t=pre[t];
	while(x!=pre[x]) {
		x=pre[x];
		pre[x]=t;
	}
	return t;
}
void merge(int x,int y) {
	if(find(x)!=find(y)) pre[find(x)]=find(y);
}

【算法代码】

对问题 http://acm.hdu.edu.cn/showproblem.php?pid=1213 利用非递归实现的并查集的代码如下:

#include <iostream>
using namespace std;
const int maxn=1005;
int pre[maxn];
//int find(int x) {
//	if(x!=pre[x]) pre[x]=find(pre[x]);
//	return pre[x];
//}
int find(int x) {
	int t=x;
	while(t!=pre[t]) t=pre[t];
	while(x!=pre[x]) {
		x=pre[x];
		pre[x]=t;
	}
	return t;
}
void merge(int x,int y) {
	if(find(x)!=find(y)) pre[find(x)]=find(y);
}
int main() {
	int T,N,M;
	int p,q;
	scanf("%d",&T);
	while(T--) {
		int ans=0;
		scanf("%d%d",&N,&M);
		for(int i=1; i<=N; i++) pre[i]=i;
		for(int i=1; i<=M; i++) {
			scanf("%d%d",&p,&q);
			merge(p,q);
		}
		for(int i=1; i<=N; i++) {
			if(find(i)==i) ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}


/*
in:
2
5 3
1 2
2 3
4 5
5 1
2 5
out:
2
4
*/

并查集压缩路径非递归写法

int find(int x){
    int temp=x;
    while(temp!=d[temp])
        temp=d[temp];
    while(x!=d[x]){
        x=d[x];
        d[x]=temp;
    }
    return temp;
}

参考文章

//www.jb51.net/article/222108.htm

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • QT使用SQLite数据库超详细教程(增删改查、对大量数据快速存储和更新)

    QT使用SQLite数据库超详细教程(增删改查、对大量数据快速存储和更新)

    这篇文章主要给大家介绍了关于QT使用SQLite数据库的相关资料,其中包括增删改查以及对大量数据快速存储和更新,SQLite是一种嵌入式关系型数据库管理系统,它是一个软件库,提供了一个自包含、无服务器、零配置的、事务性的SQL数据库引擎,需要的朋友可以参考下
    2024-01-01
  • Windows 环境下使用 Qt 连接 MySQL

    Windows 环境下使用 Qt 连接 MySQL

    这篇文章主要介绍了Windows 环境下使用 Qt 连接 MySQL的相关资料,需要的朋友可以参考下
    2017-07-07
  • C语言中的文件读写fseek 函数

    C语言中的文件读写fseek 函数

    这篇文章主要介绍是我是C语言中的文件读写fseek 函数的相关资料,fseek 函数用来移动文件流的读写位置;就好比播放器,可以直接拖拽到精彩的时间点一样,下面我们就来详细介绍该内容吧,感兴趣的小伙伴可以参考一下
    2021-10-10
  • 深入理解C语言中使用频率较高的指针与数组

    深入理解C语言中使用频率较高的指针与数组

    在C语言中要说到哪一部分最难搞,首当其冲就是指针,指针永远是个让人又爱又恨的东西,用好了可以事半功倍,用不好就会有改不完的bug和通不完的宵,下面这篇文章主要给大家介绍了关于C语言中使用频率较高的指针与数组的相关资料,需要的朋友可以参考下
    2022-03-03
  • C++中map和set的使用详细攻略

    C++中map和set的使用详细攻略

    set set是一种关联式容器,下面这篇文章主要给大家介绍了关于C++中map和set使用的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友可以参考下
    2023-02-02
  • 详析C++中的auto

    详析C++中的auto

    这篇文章主要介绍了详析C++中的auto,auto是具有自动存储器的局部变量,C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而作为一个新的类型指示符来指示编译器,下面来看看文章的详细介绍吧
    2022-01-01
  • C/C++调用Fortran的DLL的操作过程

    C/C++调用Fortran的DLL的操作过程

    这篇文章主要介绍了C/C++调用Fortran的DLL,本文以一个简单的加法器为例,通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-03-03
  • C语言源码实现停车场管理系统

    C语言源码实现停车场管理系统

    这篇文章主要为大家详细介绍了C语言源码实现停车场管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • C语言实现通讯录

    C语言实现通讯录

    这篇文章主要为大家详细介绍了C语言实现通讯录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • c语言计算三角形面积代码

    c语言计算三角形面积代码

    c语言计算三角形面积,这只是一个小作业,大家一起学习C语言吧,面积公式s = (a+b+c) / 2 area = sqrt(s * (s - a) * (s - b) * (s - c))
    2013-11-11

最新评论