程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 【筆試題】並查集實現,筆試題實現

【筆試題】並查集實現,筆試題實現

編輯:C++入門知識

【筆試題】並查集實現,筆試題實現


並查集(UnionSet)是一種樹型的數據結構,用於處理一些不相交集合)的合並及查詢問題。常常在使用中以森林來表示。

並查集實現了將N個不同的元素分成一組不相交的集合。開始時,每個元素就是一個集合,然後按規律將兩個集合進行合並。

比如:現在有 0,1,2,3,4,5,6,7,8,9 總共10個元素。它們組成了3個集合,如圖:

開始時,將每個元素都當做一個單元素的集合,並將每個元素都初始化為-1,如圖:

 根據集合按規律將兩兩集合進行合並, 6、7、8屬於0這個集合,所以把6、7、8這三個位置都置0,而0這個位置減去3;1和2這兩個集合類似,4和9都屬於1這個集合,所以將4、9這兩個位置都置為1,並將位置1的數據減2;3、5同屬於集合2,所以將位置3、5的數據置為2,將位置2的數據減去2,即:

 

這樣我們可以根據負數的個數清晰的看出有幾個集合,並且我們也可以清晰的看出某節點是屬於哪個集合的。有3個負數,所以有3個集合,3、5位置數據為2,所以它們屬於集合2;6、7、8位置的數據都為0,所以它們都屬於集合0;4、9屬於集合集合1.

集合的合並:  

形如:

把集合1合並到集合0中,集合1有1、4、9三個元素,所以,將位置1設置為0,並將位置0的數據減去3,即:

由上圖我們可以看出4、9屬於集合1,集合1又屬於集合0;此時數組中共有2個負數,因此有兩個集合!

 代碼實現:

class UnionSet
{
public:
	UnionSet(size_t size)
		:_size(size)
		, _array(new int[size])
	{
		for (int i = 0; i < size; i++)
		{ //將集合的每個元素都初始化為-1
			_array[i] = -1;
		}
	}
	//合並兩個集合
	void Merge(int root1, int root2)
	{
                //找到root1所在集合的代表元素和root2所在集合的代表元素,鏈接
		while (_array[root2] >= 0)
		{
			root2 = _array[root2];
		}
		while (_array[root1] >= 0)
		{
			root1 = _array[root1];
		}
		_array[root1] += _array[root2];
		_array[root2] = root1;
	}
	//查找root對應集合的(根)代表元素
	int Find(int root)
	{
		while (_array[root]>=0)
		{
			root = _array[root];
		}
		return root;
	}
	//打印
	void Print()
	{
		for (int i = 0; i < _size; i++)
		{
			cout << _array[i] << " ";
		}
		cout << endl;
	}

public:
	int* _array;
	size_t _size;
};

 

筆試題:

假如已知有n個人和m對好友關系(存於數組r),如果兩個人是直接的或間接的好友關系(好友的好友的好友....),則認為他們屬於同一好友圈,請求出這n個人中有幾個好友圈。

例如:n=5,m=3,r={{1,2},{2,3},{4,5}},表示有5個人,1和2是好友,2和3是好友,4和5是好友,則1.2.3屬於一個朋友圈,4.5屬於一個另朋友圈,結果為兩個朋友圈。

最後請分析所寫代碼的時間、空間復雜度。  

這個題用利用並查集實現會比較簡易和高效!

 需要建立一個函數來計算朋友圈的個數:

//計算朋友圈個數
int friends(int n, int m, int r[][2]) //n元素個數,m為每個朋友圈元素個數
{
	UnionSet uf(n + 1);
	//初始化朋友圈
	for (int i =0 ; i <= m; i++)
	{
		int first = r[i][0];
		int second = r[i][1];
		uf.Merge(first, second);
	}
	uf.Print();
	//計算朋友圈的個數
	int count = 0;
	for (int i = 1; i <= n; i++)
	{
		if (uf._array[i] < 0)
		{
			count++;
		}
	}
	return count;
}

  

代碼地址: https://github.com/Lynn-zhang/Data-Structure/blob/master/UnionSet.cpp

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved