7.3 並查集搜尋
阿新 • • 發佈:2021-11-19
並查集演算法
並查集演算法是一個利用結點關係,進行分類合組的演算法
簡介
並查集可以通過一個一維陣列來實現
我們把每一個點視作一個"獨立的,只有一個結點"的樹
之後我們可以通過一些條件,逐漸將這些樹合併成一棵大樹
合併的過程,其實就是找統一的父節點的過程,我們可以自定兩條原則:
1.相異的情況下,把右邊的父節點改為左邊的父節點。視作二者合併成了一組
2.通過兩者最高的父節點來進行比較
另外,既然我們通過層層推進找到了某個點的父節點,那麼我們在"統一"之後,也可以順便的把路上的其它結點修改,這樣會方便我們的二次尋找
程式碼示例
#include <stdio.h> int f[1001] = {0} s,n,m,sum = 0 ; //最開始的初始化 void init() { int i ; for(i=0;i<=n;i++) f[i] = i ;//最開始的時候,每個點的最高父節點就是它自己 return ; } //這是找爹的遞迴函式,不停的尋找直到找到最高父節點為止 int getf(int v) { if(f[v] == v){ return ; //“集團”內只有一個人的情況 } else { //路徑壓縮,每次在函式返回的時候,順帶把路徑上的結點都修改 f[v] = getf(f[v]) ; return f[v]; } } //合併兩個子集的函式、 void merge(int v , int u) { int t1,t2 ; //t1,t2指的是兩個子集的最高父節點 t1 = getf(v); t2 = getf(u); if(t1!=t2){ //兩者不在同一集合中,才進行合併 f[t2] = t1 ; //向左合併原則 } return ; } //主程式 int main() { int i,x,y; scanf("%d %d",&n,&m); init(); for(i=1;i<=m;i++) { scanf("%d %d",&x,&y); merge(x,y); } //掃描列印結果 for(i=1;i<=n;i++) { if(f[i] == i ) sum++; } printf("%d \n",sum); getchar();getchar() return 0 ; }
並查集也被稱為“不相交集”資料結構