并查集+基础知识点详解
并查集概念
并查集單看名字大家也能猜到這個(gè)算法的作用,是用來對(duì)集合進(jìn)行合并和查找操作
并查集是一種樹型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合(Disjoint Sets)的合并及查詢問題。——來自百度百科
就是將原本不一樣的集合,但是由于某種關(guān)系有了聯(lián)系,把他合并成同一個(gè)集合,就是實(shí)現(xiàn)一個(gè)這樣的功能。
基本操作
并查集是一種非常簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu),(我是說它的算法實(shí)現(xiàn)簡(jiǎn)單)它主要涉及兩個(gè)基本操作,分別為:
 A.合并: 合并兩個(gè)不相交集合
 B.查找: 去判斷兩個(gè)元素是否屬于同一個(gè)集合
 接下來,我會(huì)用并查集的圖形解釋來看下如何實(shí)現(xiàn)這兩個(gè)基本操作。
 1.可以看到這里有六個(gè)小球,他們代表六個(gè)不一樣的元素,用數(shù)組來表示他們,給他們附上值,來代表不一樣的集合
 
2.現(xiàn)在我來給他們一些聯(lián)系,然后可以根據(jù)聯(lián)系進(jìn)行集合的一個(gè)合并,隨機(jī)得到一個(gè)樹狀結(jié)構(gòu)
 
 只要是能通過關(guān)系串聯(lián)起來的,不管是直接聯(lián)系還是間接聯(lián)系,元素通過兩兩之間的關(guān)系串聯(lián)起來,把他們都?xì)w到同一個(gè)集合。那么如何判斷兩個(gè)元素是否屬于一個(gè)集合呢?
我們可以在每個(gè)集合內(nèi)確定一個(gè)祖宗節(jié)點(diǎn),你們可以認(rèn)為是一個(gè)特殊點(diǎn),作為參照。這樣,兩個(gè)集合只要互相確認(rèn)自己的祖宗節(jié)點(diǎn)是不是同一個(gè),就可以確定關(guān)系了。
但是還有問題啊,目前我們只知道直接的聯(lián)系,那么我們就需要對(duì)集合進(jìn)行操作,形成樹狀結(jié)構(gòu),祖宗節(jié)點(diǎn)就是根節(jié)點(diǎn),下面分別是二級(jí)、三級(jí)…。每個(gè)人只要記住自己的上級(jí)是誰(shuí)就行了。那么判斷是否屬于同一個(gè)集合,只要一層層向上查找,直到最高層,就可以在短時(shí)間內(nèi)確定了。由于我們關(guān)心的只是兩個(gè)元素是否在同一個(gè)集合的,至于他們是如何通過關(guān)系相關(guān)聯(lián)的,以及每個(gè)圈子內(nèi)部的結(jié)構(gòu)是怎樣的,甚至祖宗節(jié)點(diǎn)是誰(shuí),都不重要了,就可以隨機(jī)確定上下級(jí)關(guān)系
 3.我們最終經(jīng)過處理,實(shí)現(xiàn)的是如圖所示
 
接下來是對(duì)代碼實(shí)現(xiàn)的一個(gè)講解
一般來說,一個(gè)并查集代碼實(shí)現(xiàn)對(duì)應(yīng)三個(gè)重要步驟:初始化+查找根結(jié)點(diǎn)函數(shù)+合并集合函數(shù)
【初始化】
這個(gè)集合的類別pre(其實(shí)就是一個(gè)指針,用來指示這個(gè)集合屬于那一類,合并過后的集合,他們的pre指向的最終值一定是相同的)
 初始化的時(shí)候,每一個(gè)集合的pre都是這個(gè)集合自己的標(biāo)號(hào)。沒有跟它同類的集合,那么這個(gè)集合的源頭只能是自己了。
【查找函數(shù)】
就是找到pre指針的源頭,可以把函數(shù)命名為find,如果集合的pre等于集合的編號(hào)(即還沒有被合并或者沒有同類),那么自然返回自身編號(hào)。 如果不同(即經(jīng)過合并操作后指針指向了源頭(合并后選出的rank高的集合))那么就可以調(diào)用遞歸函數(shù),如下面的代碼:
//查找集合i(一個(gè)元素是一個(gè)集合)的源頭(遞歸實(shí)現(xiàn)) int Find(int i) {//如果集合i的父親是自己,說明自己就是源頭,返回自己的標(biāo)號(hào)if(pre[i]==i)return pre[i];//否則查找集合i的父親的源頭return Find(pre[i]); }遞歸,這個(gè)已經(jīng)講過很多次,這里就不再多講,大家可以結(jié)合瀏覽器的后退功能,如果你想追溯源頭,你就一直回溯,就能找到。
【合并】
將兩個(gè)元素所在的集合合并為一個(gè)集合。
 通常來說,合并之前,應(yīng)先判斷兩個(gè)元素是否屬于同一集合,這可用上面的"查找"操作實(shí)現(xiàn)。那么我們?nèi)绾魏喜蓚€(gè)不相交集合(Union(x,y))
 合并操作很簡(jiǎn)單:先設(shè)置一個(gè)數(shù)組pre[x],表示x的“父親”的編號(hào)。那么,合并兩個(gè)不相交集合的方法就是,找到其中一個(gè)集合祖宗節(jié)點(diǎn),將另外一個(gè)集合的祖宗節(jié)點(diǎn)的父親指向它。
算法描述總結(jié)
關(guān)鍵特征:
 ①用集合中的某個(gè)元素來代表這個(gè)集合~~,該元素稱為集合的代表元;~~
 ②構(gòu)成了一個(gè)以代表元素為根的樹形結(jié)構(gòu);
 ③對(duì)于每一個(gè)元素 pre[x]指向x在樹形結(jié)構(gòu)上的父親節(jié)點(diǎn)。如果x是根節(jié)點(diǎn),則令pre[x] = x;
 ④對(duì)于查找操作,假設(shè)需要確定x所在的的集合,也就是確定集合的代表元。可以沿著pre[x]不斷在樹形結(jié)構(gòu)中向上移動(dòng),直到到達(dá)根節(jié)點(diǎn)。
 判斷兩個(gè)元素是否屬于同一集合,只需要看他們的代表元是否相同即可。
 用途:
 1、維護(hù)無(wú)向圖的連通性。支持判斷兩個(gè)點(diǎn)是否在同一連通塊內(nèi),和判斷增加一條邊是否會(huì)產(chǎn)生環(huán)。
 2、用在求解最小生成樹的Kruskal算法里。
 如果還有哪里我講的不清楚,或是有疑問,歡迎私聊我,我會(huì)為你們解答。
貼上其他博客講解并查集的1 2 3 4
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的并查集+基础知识点详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 第三次作业:卷积神经网络基础
- 下一篇: 芝麻盐的功效与作用、禁忌和食用方法
