1. 程式人生 > 程式設計 >c++並查集優化(基於size和rank)

c++並查集優化(基於size和rank)

基於size的優化是指:當我們在指定由誰連線誰的時候,size陣列維護的是當前集合中元素的個數,讓資料少的指向資料多的集合中

基於rank的優化是指:當我們在指定由誰連線誰的時候,rank陣列維護的是當前集合中樹的高度,讓高度低的集合指向高度高的集合

執行時間是差不多的:
c++並查集優化(基於size和rank)

基於size的程式碼: UnionFind3.h

#ifndef UNION_FIND3_H_
#define UNION_FIND3_H_

#include<iostream>
#include<cassert>

namespace UF3
{
	class UnionFind
	{
	private:
		int* parent;
		int* sz;  //sz[i]就表示以i為根的集合中元素的個數
		int count;

	public:
		UnionFind(int count)
		{
			this->count = count;
			parent = new int[count]; 
			sz = new int[count];
			for(int i = 0 ; i < count ; i++)
			{
				parent[i] = i;
				sz[i] = 1;
			}

		}

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

		int find(int p)
		{
			assert(p < count && p >= 0); 
			while( p != parent[p]) //這個是寫到find裡面的
			{
				p = parent[p];
			}

			return p;
		}

		void unionElements(int p,int q)
		{

			int pRoot = find(p);
			int qRoot = find(q);

			if( pRoot == qRoot)
				return;
			if(sz[pRoot] < sz[qRoot])
			{
				parent[pRoot] = qRoot;
				sz[qRoot] += sz[pRoot];
			}
			else
			{
				parent[qRoot] = pRoot;
				sz[pRoot] += sz[qRoot];
			}

		}

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


	};
};


#endif

基於rank的程式碼: UnionFind4.h

#ifndef UNION_FIND4_H_
#define UNION_FIND4_H_

#include<iostream>
#include<cassert>

namespace UF4
{
	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 < count && p >= 0); 
			while( p != parent[p]) //這個是寫到find裡面的
			{
				p = parent[p];
			}

			return p;
		}

		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[pRoot] > rank[qRoot] )
			{
				parent[qRoot] = pRoot;
			}
			else
			{
				parent[pRoot] = qRoot; //這裡誰指向誰無所謂
				rank[qRoot] ++;
			}

		}

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


	};
};


#endif

剩下的標頭檔案和main檔案在上一個並查集的部落格中有,就不再粘貼出來了

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。