並查集是這樣的資料結構:有一大堆的資料,把一些元素放在乙個集合當中,另外一些元素放在另乙個乙個集合當中。
對於它的操作有:檢視兩個元素是否在乙個集合當中、合併兩個元素。 合併的時候採取的策略是這樣的:將兩個元素所在的集合的所有元素一起放入乙個集合當中。
這裡使用兩個字典來實現並查集:乙個字典儲存當前節點的父節點的資訊,另外乙個保持父節點大小的資訊。
classunionfindset(object):
"""並查集
"""def
__init__
(self, data_list):
"""初始化兩個字典,乙個儲存節點的父節點,另外乙個儲存父節點的大小
初始化的時候,將節點的父節點設為自身,size設為1
"""self.father_dict ={}
self.size_dict ={}
for node in
data_list:
self.father_dict[node] =node
self.size_dict[node] = 1
deffind_head(self, node):
"""使用遞迴的方式來查詢父節點
在查詢父節點的時候,順便把當前節點移動到父節點上面
這個操作算是乙個優化
"""father =self.father_dict[node]
if(node !=father):
father =self.find_head(father)
self.father_dict[node] =father
return
father
defis_same_set(self, node_a, node_b):
"""檢視兩個節點是不是在乙個集合裡面
"""return self.find_head(node_a) ==self.find_head(node_b)
defunion(self, node_a, node_b):
"""將兩個集合合併在一起
"""if node_a is none or node_b is
none:
return
a_head =self.find_head(node_a)
b_head =self.find_head(node_b)
if(a_head !=b_head):
a_set_size =self.size_dict[a_head]
b_set_size =self.size_dict[b_head]
if(a_set_size >=b_set_size):
self.father_dict[b_head] =a_head
self.size_dict[a_head] = a_set_size +b_set_size
else
: self.father_dict[a_head] =b_head
self.size_dict[b_head] = a_set_size +b_set_size
if__name__ == '
__main__':
a = [1,2,3,4,5]
union_find_set =unionfindset(a)
union_find_set.union(1,2)
union_find_set.union(3,5)
union_find_set.union(3,1)
print(union_find_set.is_same_set(2,5)) #
true
python實現並查集
class unionfind def init self self.co 0 用於記錄群的個數 self.parent 索引是每個節點本身,值是每個節點的父節點 self.size 用於記錄每個群的節點數目 def find self,x while self.parent x x self.pa...
並查集 並查集
本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...
java實現並查集
並查集是根據這篇博文學習的,寫得很不錯 下面是實現 public class unionfindset count n 合併p,q所在集合 param p param q public void union int p,int q if size rootp size rootq else coun...