考研数据结构之并查集

507 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

image.png 漏网之鱼:逻辑结构——“集合”

逻辑结构——数据元素之间的逻辑关系是什么?

集合的两个基本操作——“并”和“查”

Find ——“查”操作:确定一个指定元 素所属集合 Union ——“并”操作:将两个不想交 的集合合并为一个 注:并查集(Disjoint Set)是逻辑结 构——集合的一种具体实现,只进行 “并”和“查”两种基本操作

image.png

image.png

image.png

image.png 如何“查”到一个元素到底属于哪一个集合? —— 从指定元素出发,一路向北,找到根节点 如何判断两个元素是否属于同一个集合? —— 分别查到两个元素的根,判断根节点是否相同即可

#include<iostream>
using namespace std;
#define SIZE 13

int UFSets[SIZE];   //集合元素组 

//初始化并查集
void Initial(int S[]){
	for(int i=0;i<SIZE;i++)
		S[i]=-1;
} 

//Find "查"操作,找X所属集合(返回X所属根结点)
int Find(int S[],int X){
	while(S[X]>=0)			//循环寻找X的根 
		X=S[X];
	return X;
}


//Union "并"操作,讲两个集合合并为一个
void Union(int S[],int Root1,int Root2){
	//要求Root1与Root2是不同集合
	
	if(Root1==Root2)	return;
	
	//将根Root2连接到另一根Root1下面
	
	S[Root2]=Root1; 
		 
}


//Union "并"操作,小树合并到大树
void Union1(int S[],int Root1,int Root2){
	if(Root1==Root2)	return;
	if(S[Root2]>S[Root1]){
		S[Root1]+=S[Root2];
		S[Root2]=Root1;		//小树合并到大树 
	}else{
		S[Root2]+=S[Root1];
		S[Root1]=Root2;
		 
	} 
} 

//用并查集判断一个图有几个连通分量(图用邻接矩阵表示)
 int ComponentCount(int g[5][5]){
 	//g[5][5]是一个二维数组表示的邻接矩阵
	 int S[5];
	 for(int i=0;i<5;i++) S[i]=-1;	//定义,初始化并查集
	 
	 for(int i=0;i<5;i++)
	 	for(int j=i+1;j<5;j++)
		 if(g[i][j]>0){
		 
		 	int iRoot=Find(S,i);	
			int jRoot=Find(S,j);
			if(iRoot!=jRoot)
				Union1(S,iRoot,jRoot); 
		 
		}
	 
		 
	int count=0;
	for(int i=0;i<5;i++)
		if(S[i]<0)	count++;
		return count;	 
		 	  
 } 

//用并查集判断一个图是否有环(图用邻接矩阵表示)
int hasAcyclic(int g[5][5]){
	//g[5][5]是一个二维数组表示的邻接矩阵
	int S[5];	//初始化并查集
	for(int i=0;i<5;i++)	S[i]=-1;
	for(int i=0;i<5;i++)
		for(int j=i+1;j<5;j++)
			if(g[i][j]>0){
				int iRoot=Find(S,i);
				int jRoot=Find(S,j);
				if(iRoot!=jRoot)
					Union(S,iRoot,jRoot);
				else
					return 1;//在一个连通子图中,但凡再多一条边,必有环 
			}
	return 0;//图中没环		 
}

int main(){
		
	return 0;
}