并查集的python实现
并查集的原理很简单,参加我的csdn博客https://blog.csdn.net/cbcbcbz/article/details/60777238
这里放一个并查集的python实现
1 import numpy as np 2 import os 3 4 5 class DIS_JOIN(object): 6 def __init__(self): 7 ''' 8 并查集算法 9 拥有两个函数 10 一个是把某个元素放在某个集合中 11 另一个是返回一个list,包含所有集合和集合中所有的点 12 ''' 13 self.Set = None 14 self.Sum = None 15 self.n = None 16 17 def clear(self, n): 18 ''' 19 初始化 20 n为一共有多少个元素 21 ''' 22 self.Set = np.zeros(n, dtype = int) 23 self.Set = self.Set - 1 24 self.Sum = n 25 self.n = n 26 return 27 28 29 def find_r(self, p): 30 ''' 31 返回p属于那一个集合 32 ''' 33 if self.Set[p] < 0: 34 return p 35 36 self.Set[p] = self.find_r(self.Set[p]) 37 return self.Set[p] 38 39 40 41 def join(self, a, b): 42 ''' 43 将元素b加入元素a所在的集合中 44 ''' 45 ra = self.find_r(a) 46 rb = self.find_r(b) 47 if (ra != rb): 48 self.Set[ra] = rb 49 self.Sum = self.Sum - 1 50 return 51 52 53 def get_set(self): 54 ''' 55 返回一个list,每个元素是一个set 56 ''' 57 Set = [None] * self.Sum 58 cnt = 0 59 60 lis = [None] * self.n 61 for k in range(self.n): 62 lis[k] = [k, self.find_r(k)] 63 lis.sort(key=lambda x:(x[-1])) 64 lis.append([-100,-100]) #加一个终止条件 65 66 pre = lis[0][-1] 67 pre_poi = 0 68 69 for k in range(1, self.n + 1): 70 if lis[k][-1] != pre: 71 element_set = [None] * (k - pre_poi) 72 for i in range(pre_poi, k): 73 element_set[i - pre_poi] = lis[i][0] 74 Set[cnt] = np.array(element_set) 75 cnt = cnt + 1 76 pre = lis[k][-1] 77 pre_poi = k 78 79 return Set 80 81 82 83 84 85 86 87 if __name__ == '__main__': 88 dis_join = DIS_JOIN() 89 dis_join.clear(5) 90 dis_join.join(0,3) 91 dis_join.join(1,4) 92 Set = dis_join.get_set() 93 print(Set) 94 # for k in range(5): 95 # print(k, dis_join.find_r(k)) 96 # print(dis_join.Sum)
输出为[array([2]), array([0, 3]), array([1, 4])]
时间复杂度O(nlogn)