并查集的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)

posted @ 2018-10-01 11:30  shensobaolibin  阅读(804)  评论(2编辑  收藏  举报