欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++并查集算法簡(jiǎn)單詳解

 更新時(shí)間:2022年02月14日 10:15:37   作者:Curz酥  
大家好,本篇文章主要講的是C++并查集算法簡(jiǎn)單詳解,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下

1、并查集的初始化

并查集是用一個(gè)數(shù)組實(shí)現(xiàn)的。首先先定義一個(gè)數(shù)組:

int father[N];

father[i]表示元素i的父親結(jié)點(diǎn)。

接下來進(jìn)行初始化。一開始,每個(gè)元素都分別是獨(dú)立的一個(gè)集合,父親結(jié)點(diǎn)就是它自己,所以初始化時(shí)將所有father[i]等于i:

for(int i = 1; i <= N; i++){
    father[i] = i;
}

 這樣,就將father數(shù)組初始化完畢。

2、并查集的查找操作

由于規(guī)定同一個(gè)集合中只存在一個(gè)根結(jié)點(diǎn),因此查找操作,就是查找給定結(jié)點(diǎn)的根結(jié)點(diǎn)的過程??梢酝ㄟ^遞推或遞歸來實(shí)現(xiàn),思路都是一樣的,都是反復(fù)尋找父親結(jié)點(diǎn),直到找到根結(jié)點(diǎn)為止。

遞推代碼:

//findFather函數(shù)返回元素x所在集合的根結(jié)點(diǎn)
int findFather(int x){
    while(x != father[x]){    //如果不是根結(jié)點(diǎn),繼續(xù)循環(huán)
        x = father[x];    //獲得自己的父親結(jié)點(diǎn)
    }
    return x;
}

上述代碼中, while(x != father[x]),說明當(dāng)x的父親結(jié)點(diǎn)不等于本身時(shí),也就是x不是根結(jié)點(diǎn)時(shí)就繼續(xù)循環(huán),因?yàn)楦赣H結(jié)點(diǎn)等于本身這個(gè)情況,只有在根結(jié)點(diǎn)才會(huì)出現(xiàn)。

遞歸代碼:

int findFather(int x){
    if(x == father[x]) return x;    //如找到根結(jié)點(diǎn),就返回根結(jié)點(diǎn)編號(hào)x
    else return findFather(father[x]); //否則,遞歸判斷x的父親結(jié)點(diǎn)是否是根結(jié)點(diǎn)
}

3、并查集的合并操作

合并,就是把兩個(gè)集合合并成一個(gè)集合。實(shí)現(xiàn)過程是:先判斷兩個(gè)元素是否屬于同一個(gè)集合,不屬于同一個(gè)集合,就開始進(jìn)行合并操作。判斷兩個(gè)元素是否屬于同一個(gè)集合的具體思路,就是調(diào)用上面的findFather函數(shù),分別查找兩個(gè)元素所屬集合的根結(jié)點(diǎn),根結(jié)點(diǎn)不同,則兩個(gè)元素不屬于同一個(gè)集合。合并兩個(gè)集合的具體思路,就是將其中一個(gè)集合的根結(jié)點(diǎn)的父親指向另外一個(gè)集合的根結(jié)點(diǎn)即可。

合并操作的代碼實(shí)現(xiàn):(假設(shè)有兩個(gè)集合,一個(gè)集合里有元素a,一個(gè)集合有元素b)

void Union(int a, int b){
    //讓一個(gè)集合的根結(jié)點(diǎn)的父親指向另一個(gè)集合的根結(jié)點(diǎn)
    father(findFather(a)) = findFather(b); 
}

注意,合并操作之前,最好先判斷下待合并的兩個(gè)元素是否位于同一個(gè)集合。

4、為什么要路徑壓縮?

5、實(shí)現(xiàn)路徑壓縮

由于findFather函數(shù)目的就是查找根結(jié)點(diǎn),所以,我們?cè)诓檎医Y(jié)點(diǎn)的路徑上直接將所有結(jié)點(diǎn)的父親都指向根結(jié)點(diǎn),查找的時(shí)候就不必一直回溯去尋找父親了,查詢的復(fù)雜度可以降為O(1)。

比如下面這張圖:

觀察圖不難發(fā)現(xiàn),上圖中father[1] = 1,father[2] = 1,father[3] = 2,father[4] = 3。經(jīng)過路徑壓縮,就變成下面這幅圖:

相當(dāng)于將所有結(jié)點(diǎn)的父親都直接指向根結(jié)點(diǎn),這就是路徑壓縮。

如何用代碼實(shí)現(xiàn)路徑壓縮呢?以下是具體代碼:

int findFather(int x){
    if(father[x] != x) father[x] = findFather(father[x]);
    return father[x];
}

 以上代碼,實(shí)現(xiàn)了在查詢獲取根結(jié)點(diǎn)的同時(shí),將路徑進(jìn)行壓縮優(yōu)化,代碼雖然很短,但是很巧妙,下面解釋下上述代碼:

 if(father[x] != x),當(dāng)所查找的元素x的父親結(jié)點(diǎn)不是自己,也就是x不是根結(jié)點(diǎn)時(shí),

findFather(father[x]),就繼續(xù)遞歸查找父結(jié)點(diǎn),直到找到根結(jié)點(diǎn)為止,

father[x] = findFather(father[x]),然后將找到的根結(jié)點(diǎn)直接賦給x的父親結(jié)點(diǎn)。

這樣就實(shí)現(xiàn)了路徑壓縮,即將結(jié)點(diǎn)的父親直接指向根結(jié)點(diǎn)。

return father[x],返回查找到的根結(jié)點(diǎn)。

總結(jié)

到此這篇關(guān)于C++并查集算法簡(jiǎn)單詳解的文章就介紹到這了,更多相關(guān)C++并查集算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入分析C++中聲明與定義的區(qū)別

    深入分析C++中聲明與定義的區(qū)別

    C++學(xué)了這么多年你知道為什么定義類時(shí),類的定義放在.h文件中,而類的實(shí)現(xiàn)放在cpp文件中。它們?yōu)槭裁茨軌蜿P(guān)聯(lián)到一起呢?你知道什么東西可以放在.h文件中,什么不能。什么東西又可以放在cpp文件中。如果你忘記了或是壓根就不明白,那么讀過此文你會(huì)清晰無比?。?/div> 2014-09-09
  • 淺談C++的語句語法與強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換

    淺談C++的語句語法與強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換

    這篇文章主要介紹了淺談C++的語句語法與強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • c++中深淺拷貝以及寫時(shí)拷貝的實(shí)現(xiàn)示例代碼

    c++中深淺拷貝以及寫時(shí)拷貝的實(shí)現(xiàn)示例代碼

    這篇文章主要給大家介紹了關(guān)于c++中深淺拷貝以及寫時(shí)拷貝實(shí)現(xiàn)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • VTK8.1?在?Qt5.9?環(huán)境下的配置編譯和安裝過程

    VTK8.1?在?Qt5.9?環(huán)境下的配置編譯和安裝過程

    為了實(shí)現(xiàn)realsense的PCL點(diǎn)云顯示,需要VTK支持。由于整個(gè)平臺(tái)在Qt環(huán)境實(shí)現(xiàn),VTK編譯為Qt插件。整個(gè)過程并不復(fù)雜,網(wǎng)上的文章大多不全,自己梳理了一下,分享出來,需要的朋友可以參考下
    2022-07-07
  • 一文秒懂C語言/C++內(nèi)存管理(推薦)

    一文秒懂C語言/C++內(nèi)存管理(推薦)

    在C++中,內(nèi)存分為:棧、堆、自由存儲(chǔ)區(qū)、全局/靜態(tài)存儲(chǔ)區(qū)、常量存儲(chǔ)區(qū)。這篇文章主要介紹了一文秒懂C語言/C++內(nèi)存管理,需要的朋友可以參考下
    2020-11-11
  • C++通用動(dòng)態(tài)抽象工廠的實(shí)現(xiàn)詳解

    C++通用動(dòng)態(tài)抽象工廠的實(shí)現(xiàn)詳解

    在面向?qū)ο蟮木幊讨?一般通過繼承和虛函數(shù)來提供抽象能力,下面這篇文章主要給大家介紹了關(guān)于C++通用動(dòng)態(tài)抽象工廠的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • C語言之通訊錄的模擬實(shí)現(xiàn)代碼

    C語言之通訊錄的模擬實(shí)現(xiàn)代碼

    這篇文章主要介紹了C語言之通訊錄的模擬實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • C++深入了解模板的使用

    C++深入了解模板的使用

    這篇文章主要介紹了C++中模板(Template)的詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • C++淺析析構(gòu)函數(shù)的特征

    C++淺析析構(gòu)函數(shù)的特征

    既然在創(chuàng)建對(duì)象時(shí)有構(gòu)造函數(shù)(給成員初始化),那么在銷毀對(duì)象時(shí)應(yīng)該還有一個(gè)清除成員變量數(shù)據(jù)的操作咯,析構(gòu)函數(shù)與構(gòu)造函數(shù)功能相反,析構(gòu)函數(shù)不是完成對(duì)象的銷毀,局部對(duì)象銷毀工作是由編譯器完成的。而對(duì)象在銷毀時(shí)會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù),完成類的一些資源清理工作
    2022-07-07
  • STL區(qū)間成員函數(shù)及區(qū)間算法總結(jié)

    STL區(qū)間成員函數(shù)及區(qū)間算法總結(jié)

    這篇文章主要匯總介紹了STL區(qū)間成員函數(shù)及區(qū)間算法,有需要的小伙伴可以參考下。
    2015-07-07

最新評(píng)論