并查集实现
并查集是什么東西?
它是用來(lái)管理元素分組情況的一種數(shù)據(jù)結(jié)構(gòu)。
他可以高效進(jìn)行兩個(gè)操作:
萌新可能不知所云,這個(gè)結(jié)構(gòu)到底有什么用?
經(jīng)分析,并查集效率之高超乎想象,對(duì)n個(gè)元素的并查集進(jìn)行一次操作的復(fù)雜度低于O(logn)
?
我們先說(shuō)并查集是如何實(shí)現(xiàn)的:
也是使用樹(shù)形結(jié)構(gòu),但不是二叉樹(shù)。
每個(gè)元素就是一個(gè)結(jié)點(diǎn),每組都是一個(gè)樹(shù)。
無(wú)需關(guān)注它的形狀,或哪個(gè)節(jié)點(diǎn)具體在哪個(gè)位置。
?
初始化:
我們現(xiàn)在有n個(gè)結(jié)點(diǎn),也就是n個(gè)元素。
?
合并:
然后我們就可以合并了,合并方法就是把一個(gè)根放到另一顆樹(shù)的下面,也就是整棵樹(shù)作為人家的一個(gè)子樹(shù)。
?
查詢:
查詢兩個(gè)結(jié)點(diǎn)是否是同一組,需要知道這兩個(gè)結(jié)點(diǎn)是不是在一棵樹(shù)上,讓他們分別沿著樹(shù)向根找,如果兩個(gè)元素最后走到一個(gè)根,他們就在一組。
?
當(dāng)然,樹(shù)形結(jié)構(gòu)都存在退化的缺點(diǎn),對(duì)于每種結(jié)構(gòu),我們都有自己的優(yōu)化方法,下面我們說(shuō)明如何避免退化。
這樣查詢的時(shí)候就能很快地知道根是誰(shuí)了。
?
下面上代碼實(shí)現(xiàn):
和很多樹(shù)結(jié)構(gòu)一樣,我們沒(méi)必要真的模擬出來(lái),數(shù)組中即可。
int p[MAX_N];//父親 int rank[MAX_N];//高度 //初始化 void gg(int n) {for(int i=0;i<n;i++){p[i]=i;//父是自己代表是根rank[i]=0;} } //查詢根 int find(int x) {if(p[x]==x)return x;return p[x]=find(p[x])//不斷把經(jīng)過(guò)的結(jié)點(diǎn)連在根 } //判斷是否屬于同一組 bool judge(int x,int y) {return find(x)==find(y);//查詢結(jié)果一樣就在一組 } //合并 void unite(int x,int y) {if(x==y)return;if(rank[x]<rank[y])p[x]=y;//深度小,放在大的下面else{p[y]=x;if(rank[x]=rank[y])rank[x]++;//一樣,y放x后,x深度加一} }實(shí)現(xiàn)很簡(jiǎn)單,應(yīng)用有難度,以后有時(shí)間更新題。
?
總結(jié)
- 上一篇: 《Head First设计模式》第六章笔
- 下一篇: leetcode 231. 2的幂