成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

python實現(xiàn)一個簡單的并查集

wawor4827 / 3339人閱讀

摘要:并查集是一種樹型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合的合并及查詢問題。在構(gòu)造函數(shù)中新建一個數(shù)組,表示節(jié)點所在的集合的樹的高度。以上是實現(xiàn)一個簡單的并查集的方式。

并查集是一種樹型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合的合并及查詢問題。常常在使用中以森林來表示。

并查集有三種基本操作,獲得根節(jié)點,判斷兩節(jié)點是否連通,以及將兩不連通的節(jié)點相連(相當(dāng)于將兩節(jié)點各自的集合合并)

用UnionFind類來表示一個并查集,在構(gòu)造函數(shù)中,初始化一個數(shù)組parent,parent[i]表示的含義為,索引為i的節(jié)點,它的直接父節(jié)點為parent[i]。初始化時各個節(jié)點都不相連,因此初始化parent[i]=i,讓自己成為自己的父節(jié)點,從而實現(xiàn)各節(jié)點不互連。

    def __init__(self, n):
        self.parent = list(range(n))

由于parent[i]僅表示自己的直接父節(jié)點,查詢兩個節(jié)點是否相交需要比較它們的根節(jié)點是否相同。因此要封裝一個查詢自己根節(jié)點的方法。

    def get_root(self, i):
        while i != self.parent[i]:
            i = self.parent[i]

        return i

接下來可以通過來比較根節(jié)點是否相同來判斷兩節(jié)點是否連通。

    def is_connected(self, i, j):
        return self.get_root(i) == self.get_root(j)

當(dāng)要連通兩個節(jié)點時,我們要將其中一個節(jié)點的根節(jié)點的parent,設(shè)置為另一個節(jié)點的根節(jié)點。注意,連通兩個節(jié)點并非僅僅讓兩節(jié)點自身相連,實際上是讓它們所屬的集合實現(xiàn)合并。

    def union(self, i, j):
        i_root = self.get_root(i)
        j_root = self.get_root(j)
        self.parent[i_root] = j_root

接下來我們做兩個小優(yōu)化。
由于調(diào)用get_root時需要通過不斷找自己的直接父節(jié)點,來尋找根節(jié)點,如果這棵樹的層級過深,會導(dǎo)致性能受到嚴(yán)重影響。因此我們需要在union時,盡可能的減小合并后的樹的高度。
在構(gòu)造函數(shù)中新建一個數(shù)組rank,rank[i]表示節(jié)點i所在的集合的樹的高度。

因此,當(dāng)合并樹時,分別獲得節(jié)點i和節(jié)點j的root i_root和j_root之后,我們通過訪問rank[i_root]和rank[j_root]來比較兩棵樹的高度,將高度較小的那棵連到高度較高的那棵上。如果高度相等,則可以隨便,并將rank值加一。

    def union(self, i, j):
        i_root = self.get_root(i)
        j_root = self.get_root(j)

        if self.rank[i_root] == self.rank[j_root]:
            self.parent[i_root] = j_root
            self.rank[j_root] += 1
        elif self.rank[i_root] > self.rank[j_root]:
            self.parent[j_root] = i_root
        else:
            self.parent[i_root] = j_root

通過對union操作的改良可以防止樹的高度過高。我們還可以對get_root操作本身進行優(yōu)化。
當(dāng)前每次執(zhí)行g(shù)et_root時,需要一層一層的找到自己的父節(jié)點,很費時。由于根節(jié)點沒有父節(jié)點,并且文章開始處提到過如果一個節(jié)點沒有父節(jié)點,那么它的父節(jié)點就是自己,因此可以說只有根節(jié)點的父節(jié)點是自己本身。現(xiàn)在我們加上一個判斷,判斷當(dāng)前節(jié)點的父節(jié)點是否為根節(jié)點,如果不為根節(jié)點,就遞歸地將自己的父節(jié)點設(shè)置為根節(jié)點,最后返回自己的父節(jié)點。

    def get_root(self, i):
        if self.parent[i] != self.parent[self.parent[i]]:
            self.parent[i] = self.get_root(self.parent[i])
        return self.parent[i]

以上是python實現(xiàn)一個簡單的并查集的方式。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/45553.html

相關(guān)文章

  • 面試??妓惴}之并查集問題

    摘要:很顯然,我們可以使用并查集來求解。并查集是用來將一系列的元素分組到不相交的集合中,并支持合并和查詢操作。理論總是過于抽象化,下面我們通過一個例子來說明并查集是如何運作的。采用這個方法,我們就可以寫出最簡單版本的并查集代碼。朋友圈問題現(xiàn)在有 105個用戶,編號為 1- 105。已知有 m 對關(guān)系,每一對關(guān)系給你兩個數(shù) x 和 y ,代表編號為 x 的用戶和編號為 y 的用戶是在一個圈子中,例如...

    番茄西紅柿 評論0 收藏2637
  • [Leetcode] Graph Valid Tree 圖與樹

    摘要:這樣就將一個集合的節(jié)點歸屬到同一個集合號下了。最后如果并查集中只有一個集合,則說明可以構(gòu)建樹。 Graph Valid Tree Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check w...

    luqiuwen 評論0 收藏0
  • leetcode200. Number of Islands

    摘要:題目要求提供一個二維數(shù)組表示一張地圖,其中代表陸地,代表海洋。這里使用一個新的二維數(shù)組來表示對應(yīng)地圖上的元素屬于哪個并查集。在合并的時候先進行判斷,如果二者為已經(jīng)相連的陸地,則無需合并,否則將新的二維數(shù)組上的元素指向所在的并查集。 題目要求 Given a 2d grid map of 1s (land) and 0s (water), count the number of isla...

    Zoom 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<