【python刷題】並查集

什麼是並查集?

這裏借用百度百科的一句話:並查集是一種樹型的數據結構,用於處理一些不相交集合(disjoint sets)的合併及查詢問題。常常在使用中以森林來表示。假設現在有一個武林大會,包含了少林、峨嵋、武當等門派,通過並查集就可以將每個人歸類到自己的門派中。

代碼實現

class UnionFind:
    def __init__(self):
        self.co = 0  # 用於記錄羣的個數
        self.parent = []  # 索引是每個節點本身,值是每個節點的父節點
        self.size = []  # 用於記錄每個羣的節點數目

    #
    def find(self, x):
        while self.parent[x] != x:
            # self.parent[x] = self.parent[self.parent[x]]  # 用於路徑壓縮
            x = self.parent[x]
        return x

    def union(self, p, q):
        rootP = self.find(p)
        rootQ = self.find(q)
        if rootP == rootQ:
            return
        # 下面的這個if語句用將節點數少的合併到節點數多的羣中
        if self.size[rootP] > self.size[rootQ]:
            self.parent[rootQ] = rootP
            self.size[rootP] += self.size[rootQ]
        else:
            self.parent[rootP] = rootQ
            self.size[rootQ] += self.size[rootP]
        self.co -= 1

    # 用於判斷p和q之間是否連通,如果兩個節點的父節點是相同的,那麼就是連通的
    def connected(self, p, q):
        rootP = self.find(p)
        rootQ = self.find(q)
        return rootP == rootQ

    # 返回有多少個羣
    def count(self):
        return self.co

    # 初始化,節點的父節點就是其本身,假設n=10,那麼就有10個羣,self.parent=[0,1,2,3,4,5,6,7,8,9],self.parent[0]=0表示0節點的父節點是0。每個羣的size,也就是包含的節點數目就是1,self.size[0]=1。
    def uf(self, n):
        self.co = n
        self.parent = [0 for _ in range(n)]
        self.size = [0 for _ in range(n)]
        for i in range(n):
            self.parent[i] = i
            self.size[i] = 1

unionF = UnionFind()
unionF.uf(10)
print("初始化每個節點的父節點:", unionF.parent)
print("初始化的羣個數:", unionF.count())
unionF.union(0, 3)  # 0,3建立關係
unionF.union(3, 7)  # 3,7建立關係
unionF.union(7, 9)  # 7,9建立關係
unionF.union(2, 8)  # 2,8建立關係
print("判斷{}與{}之間是否在一個羣裏面:{}".format(3, 8, unionF.connected(3, 8)))
print("返回節點{}的父節點{}".format(7, unionF.find(7)))
print("當前每個節點的父節點:", unionF.parent)
print("當前羣的個數:", unionF.count())
print("當前每一個羣的節點個數:", unionF.size)

結果:

初始化每個節點的父節點: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
初始化的羣個數: 10
判斷3與8之間是否在一個羣裏面:False
返回節點7的父節點3
當前每個節點的父節點: [3, 1, 8, 3, 4, 5, 6, 3, 8, 3]
當前羣的個數: 6
當前每一個羣的節點個數: [1, 1, 1, 4, 1, 1, 1, 1, 2, 1]

更具體的介紹可以去參考labuladong的算法小抄。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章