C++实现及理论https://www.cnblogs.com/polly333/category/720001.html
https://github.com/liuyubobobo/Play-with-Algorithms
python实现https://github.com/ShiveryMoon/Imooc-Algorithm-PythonEdition
经过路径压缩后,时间复杂度近乎为O(1)
并查集——查
def find(self,p):#查 if p>=0 and p<self.count: while p != self.parent[p]: self.parent[p]=self.parent[self.parent[p]]#这一行代码修改了树结构 p=self.parent[p] return p #if p != self.parent[p]: 传说中那更精彩的回答 #self.parent[p]=self.find(self.parent[p]) #return parent[p] else: raise KeyError('Key not in parent')
并查集——并(优化:避免并查集过长)
def Union(self,p,q):#并 pRoot,qRoot=self.find(p),self.find(q)#找到p,q指向的根 if pRoot==qRoot: return #避免并集树过长,基于rank优化,rank[i]表示根节点为i的树的高度 if self.rank[pRoot]<self.rank[qRoot]: self.parent[pRoot]=qRoot elif self.rank[pRoot]>self.rank[qRoot]: self.parent[qRoot]=pRoot else: self.parent[pRoot]=qRoot self.rank[qRoot]+=1 #基于size优化,size指本身节点+所有子节点数量 if self.size[pRoot]<self.size[qRoot]: self.parent[pRoot] = qRoot self.size[qRoot]+=self.size[pRoot] else: self.parent[qRoot]=pRoot; self.size[pRoot]+=self.size[qRoot]
路径压缩(父节点的父节点)
节点4、节点2路径压缩
通过递归压缩路径
while p != self.parent[p]: self.parent[p]=self.parent[self.parent[p]]#路径压缩优化,这一行代码修改了树结构 p=self.parent[p] return p #if p != self.parent[p]: 传说中那更精彩的回答,递归到最终根节点,路径压缩 #self.parent[p]=self.find(self.parent[p]) #return parent[p]完整代码
# -*- coding: utf-8 -*- class UnionFind(object): def __init__(self,count=10): self.count=count self.rank=[1 for x in range(count)] self.parent=[x for x in range(count)] self.size =[1 for x in range(count)] #初始化时所有元素都不互连 def find(self,p): if p>=0 and p<self.count: while p != self.parent[p]: self.parent[p]=self.parent[self.parent[p]]#路径压缩优化,这一行代码修改了树结构 p=self.parent[p] return p #if p != self.parent[p]: 传说中那更精彩的回答,递归到最终根节点,路径压缩 #self.parent[p]=self.find(self.parent[p]) #return parent[p] else: raise KeyError('Key not in parent') def isConnected(self,p,q): return self.find(p) == self.find(q) def Union(self,p,q): pRoot,qRoot=self.find(p),self.find(q)#找到p,q指向的根 if pRoot==qRoot: return #避免并集树过长 #基于rank优化,rank[i]表示根节点为i的树的高度 if self.rank[pRoot]<self.rank[qRoot]: self.parent[pRoot]=qRoot elif self.rank[pRoot]>self.rank[qRoot]: self.parent[qRoot]=pRoot else: self.parent[pRoot]=qRoot self.rank[qRoot]+=1 #基于size优化,size指本身节点+所有子节点数量 if self.size[pRoot]<self.size[qRoot]: self.parent[pRoot] = qRoot self.size[qRoot]+=self.size[pRoot] else: self.parent[qRoot]=pRoot; self.size[pRoot]+=self.size[qRoot] uf=UnionFind(10) uf.Union(1,2) uf.Union(1,3) uf.Union(4,5) uf.Union(4,6) uf.Union(3,6) print(uf.isConnected(3,5)) print(uf.size) print(uf.rank) ''' 0 1 7 8 9 / | \ 2 3 4 / \ 5 6 '''