数据结构并查集

并查集

#include<iostream>
#define VERTICES 6
using namespace std;

void initialise(int parent[],int rank[]){//初始化数组,rank树高 
	int i;
	for(i=0;i<VERTICES;i++){
		parent[i]=-1;
		rank[i]=0;
	}
}

int find_root(int x,int parent[]){
	int x_root = x;
	while(parent[x_root]!=-1){
		x_root = parent[x_root];
	}
	return x_root;
}

// 1 union successfully, 0 -failed
int union_vertices(int x, int y, int parent[],int rank[]){
	int x_root = find_root(x,parent);//0  1   1/2 
	int y_root = find_root(y,parent);//1  2   3
	if(x_root == y_root){//如果两树的根相同 
		return 0;
	}else{
		//parent[x_root]=y_root;
		/*
		以上按照数组中的边数和顶点数连接 
		以下路径压缩 
		*/
		if(rank[x_root] > rank[y_root]){
			parent[y_root] = x_root;
		}else if(rank[y_root] > rank[x_root]){
			parent[x_root] = y_root;
		}else{
			parent[x_root] = y_root;
			rank[y_root]++;//当两树的根相同时,树高加1 
		}
		return 1;
	}
}//检测是否有环 

int main(){
	int parent[VERTICES]={0};
	int rank[VERTICES] = {0};//路径压缩功能数
	int edges[6][2]{
		{0,1},{1,2},{1,3},
		{3,4},{2,5},{5,4}
	};
	initialise(parent,rank);//将数组初始化为-1 
	for(int i=0;i<6;i++){
		int x = edges[i][0];
		int y = edges[i][1];
		if(union_vertices(x,y,parent,rank)==0){
			cout<<"Cycle detected!"<<endl;
			exit(0);
		}
	}
	cout<<"not Cycle found"<<endl;
	system("0");
	return 0;
} 

在这里插入图片描述
在这里插入图片描述
以上是并查集建立树和路径压缩的代码
实际应用:

在这里插入图片描述
其实就是将数组中的有关系的元素连成一棵树,对应数组中有几个负数就是有几棵树,即该学校有几个社团。
实例: {1,2,3}为一棵树
{4,5}为一棵树
_set[]:{-,1,1,-,4}("-"表示负数)

#include<iostream>
#pragma once
using namespace std;

class UnionSet {
public:
	UnionSet(int n = 6) {//初始化parent[] 
		for (int i = 0; i < 6; i++) {
			_set[i] = -1;
		}
		_n = n;
	}
	int GetRoot(int p) {//得到树根的下标 
		while (_set[p] >= 0) {//寻根 
			p = _set[p];
		}
		return p;
	}
	void UnionFriends(int p1, int p2) {//parent[][] 
		int root1 = GetRoot(p1);
		int root2 = GetRoot(p2);
		if (root1 != root2) {
			_set[root1] = _set[root1] + _set[root2];
			_set[root2] = root1;//建立树,将不同根的节点树连接 
		}
	}
	int friends(int n, int m, int r[][2]) {//并查集主功能函数 
		int count = 0;
		for (int i = 0; i < m; i++) {
			UnionFriends(r[i][0], r[i][1]);
		}
		for (int i = 1; i < n + 1; i++)
		{
			if (_set[i] < 0) {
				count++;
			}

		}
		return count;
	}
private:
	int _set[6];
	int _n;


};


int main() {
	int n = 5, m = 3;//n人数,m好友关系
	int r[3][2] = {
		{1,2},{2,3},{4,5}//有三个关系,其中两个关系重叠,总共有两个社团 
	};
	UnionSet us;
	int ret = us.friends(n, m, r);
	cout << "社团的人数为:" << ret << endl;
	system("pause");
	return 0;
}

发布了19 篇原创文章 · 获赞 4 · 访问量 1252

猜你喜欢

转载自blog.csdn.net/weixin_43427728/article/details/102757665
今日推荐