并查集:实现方式⑤

#include<iostream>
#include<cassert>
#include<ctime>

using namespace std;

class UnionFind
{
private:
	int* parent;
	int* rank;//rank[i]表示以i为根节点的集合所表示的数的层数
	int count;
public:
	UnionFind(int count)
	{
		this->count = count;
		parent = new int[count];
		rank = new int[count];
		for (int i = 0; i < count; i++)
		{
			parent[i] = i;
			rank[i] = 1;//初始的时候每个集合互相独立,假设每一个初始的节点在第一层层数从一开始
		}
	}

	~UnionFind()
	{
		delete[] parent;
		delete[] rank;
	}

	int find(int p)
	{
		assert(p >= 0 && p < count);
		while (p != parent[p])
		{
			parent[p] = parent[parent[p]];
			p = parent[p];
		}
		return p;
	}

	bool isConnected(int p, int q)
	{
		return find(p) == find(q);
	}

	void UnionElements(int p, int q)
	{
		int pRoot = find(p);
		int qRoot = find(q);

		if (pRoot == qRoot)
		{
			return;
		}
		if (rank[pRoot] < rank[qRoot])
		{
			parent[pRoot] = qRoot;
		}
		else if(rank[qRoot]<rank[pRoot])
		{
			parent[qRoot] = pRoot;
		}
		else
		{
			//rank[pRoot]==rank[qRoot]
			parent[pRoot] = qRoot;
			rank[qRoot] += 1;//p接到q根节点的后面,q的总体层数加一
		}
	}
};


void testUF05(int n)
{
	srand(time(NULL));
	UnionFind uf = UnionFind(n);

	for (int i = 0; i < n; i++)
	{
		int a = rand() % n;
		int b = rand() % n;
		uf.UnionElements(a, b);
	}

	for (int i = 0; i < n; i++)
	{
		int a = rand() % n;
		int b = rand() % n;
		cout << a <<"\t"<< b <<"\t"<< uf.isConnected(a, b) << endl;;
	}
}

int main()
{
	testUF05(10000);
	system("pause");
	return 0;
}
发布了27 篇原创文章 · 获赞 23 · 访问量 259

猜你喜欢

转载自blog.csdn.net/dosdiosas_/article/details/105557287