談一談并查集QAQ(上)

最近幾日理了理學過的很多oi知識。。。發現不知不覺就有很多的知識忘記了。。。

在聊聊并查集的時候順便當作鞏固吧。。。。

什么是并查集呢?

( Union Find Set ) 是一種用于處理分離集合的抽象數據結構類型。

具體一點:

  當我們給出兩個元素的一個無序對(a,b)時,需要快速合并a和b所在的集合,這期間需要反復查找出某元素所在的集合,“并”、“查”和“集”三字由此而來。也就是說,并查集的作用是動態地維護和處理集合元素之間的復雜關系。

  在并查集中,n個不同的元素被分為若干組,每組是一個集合,這種集合就叫做“分離集合”。并查集支持查找一個元素所屬的集合以及兩個元素各自所屬集合的合并操作。

例如,我們有這樣一個問題:

  一個城鎮里居住著n個市民,已知一些人互為朋友,而且朋友的朋友也是朋友,也就是說,如果A和B是朋友,C和B是朋友,則A和C也是朋友,請你根據給出的若干組朋友關系,求出最大的一個朋友圈的人數。

  這就有了并查集的用武之地了,一開始我們把所有人都各自放在一個集合中,然后根據依次給出的朋友關系,查找判斷兩個人是否屬于同一個集合(是否已經是朋友),如果不在同一個集合,則將這兩個集合合并成一個集合(行成一個朋友圈),最后看哪個集合的元素最多并輸出個數即可。

然而并查集有什么主要操作呢?

  使用并查集首先要記錄一組分離的動態集合S = {S1,S2,···,Sn},每個集合還要設置一個代表來識別,代表只是要選擇該集合中的某個元素即可,哪一個元素被選作代表是無所謂的,重要的是,如果請求某一動態集合的代表兩次,且在兩次請求間不修改集合,則兩次得到的答案應該是相同的。并查集主要有三種操作:初始化、查找與合并。

  (1)初始化:make-set(x)

  建立一個新的集合,其僅有的成員是x(同時就是代表)。由于各集合是分離的,所以要求x在沒有其他集合中出現過。使用并查集前都需要執行一次初始化操作,無論采用何種實現方式,其時間復雜度都是O(n)。

  (2)查找:find-set(x)

  查找一個元素所在的集合,本操作返回一個包含x的集合的代表。查找是并查集的核心操作,也是優化并查集效率的重點。

  (3)合并:merge(x,y)

  將包含x和y的動態集合(假設為Sx和Sy)合并成一個新的集合S,本操作返回集合Sx∪Sy的代表。一般來說,在不同的實現中通常以Sx或者Sy的代表作為新集合的代表。合并之前一般要先判斷兩個元素是否屬于同一集合,這可以通過查找操作來實現。

終于到了并查集的實現了!!

  并查集可以采用數組、鏈表和樹三種數據結構來實現,選擇不同的實現方式會給查找操作和合并操作的效率帶來很大的差別。

并查集的數組實現:

  實現并查集的最簡單的方法就是用數組記錄每個元素所屬集合的編號,A[i] = j 表示元素i屬于第j 類集合,初始化A[i] = i。查找元素所屬的集合時,只需讀出數組中記錄的該元素所屬集合的編號A[i],時間復雜度為O(1)。合并兩個元素各自所屬集合時,需要將數組中屬于其中一個集合的元素所對應的數組元素值全部更新為另一個集合的編號值,時間復雜度為O(n)。所以用數組實現并查集是最簡單的方法,而且容易理解,實際使用較多。但是,合并操作的代價太高,在最壞的情況下,所有集合合并成一個集合的總代價會達到O(n2)。

并查集的鏈表實現:

  用鏈表實現并查集也是一種很常見的手段。每個分離集合對應一個鏈表,鏈表有一個表頭,每個元素有一個指針指向表頭,表明了它所屬集合的類別,另設一個指針指向它的下一個元素,同時為了方便實現,再設一個指針last表示鏈表的表尾。

  因為并查集問題處理的對象往往都是連續的整數,所以一般選擇用靜態數組來模擬鏈表,用下標對應集合的元素。具體數據結構體定義如下qwq:

?

struct node{int head,next,last;
}S[maxn];

  

  此時,初始化和查找操作的實現就很簡單了。

?

make-set(x){S[x].head = x;S[x].next = 0;
}
find-set(x){return S[x].head;
}

?

  對于合并操作,我們先假設merge(x,y)的參數是有序的,是把y所屬的集合合并到x所在的集合。首先執行查找操作,當出現find-set(x)≠ find-set(y)時,直接將y的表頭接到x的表尾,同時將y所在集合的所有元素head值設為find-set(x),x的表尾也設為y的表尾。需要注意的是,last指針只要在表頭結點中記錄即可,因為每一次查找到find-set(x)都可以得到表頭元素,而鏈表中其他元素記錄last值是毫無意義的。

  考慮到輸入數據的特殊性,根據以上合并方法,我們總是把y接到x后面,如果y所在的集合非常大,每次復制的代價就會非常高,比如輸入數據形如:(2,1),(3,1),(4,1),·····,(n,1),顯然y所在的集合就會越來越龐大,此時時間復雜度就會達到O(n2)。不過,我們可以很快滴想到一個優化方法:不妨比較x和y所在集合的大小,把較短的鏈表接在較長的鏈表尾部,這樣效果是一樣的,但時間效率肯定不比原來差。具體實現時可以在node里多設一個number域,用來記錄此條鏈表中成員的個數。顯然,number記錄在表頭元素中即可。將兩個鏈表合并的時候,只需要將鏈表的number域相加,因此維護起來是非常方便的。這種快速實現的方法稱為“加權啟發式”合并,這里的權就是指number域。假設有n個元素,則可以證明這種方法合并操作的總次數不超過nlog2n次。

?

merge(x,y){x = find-set(x);y = find-set(y);if(x.number > y.number)merge(x,y);merge(y,x);
}

  

  以上是并查集的兩種實現方法qwq。然而最最最重要以及實用的是并查集的樹實現。我會在? 談一談并查集QAQ(下) 中仔細講解qwq。

?

  

?

轉載于:https://www.cnblogs.com/excellent-zzy/p/10686911.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249192.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249192.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249192.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue的雙向綁定原理及實現

前言 使用vue也好有一段時間了,雖然對其雙向綁定原理也有了解個大概,但也沒好好探究下其原理實現,所以這次特意花了幾晚時間查閱資料和閱讀相關源碼,自己也實現一個簡單版vue的雙向綁定版本,先上個成果圖來吸引各位&a…

python后端將svc文件數據讀入數據庫具體實現

如何用python將svc文件的數據讀入到MySQL數據庫里,在此直接上代碼了,感興趣的朋友可以貼代碼測試: import pandas as pd import os from sqlalchemy import create_engine # 初始化數據庫連接,使用pymysql模塊 # MySQL的用戶&…

作業——8

這個作業屬于哪個課程C語言程序設計Ⅱ這個作業的要求在哪里C語言作業評價標準我在這個課程的目標是指針與字符串這個作業在哪個具體方面幫助我實現目標使用指針與字符串參考文獻指針和字符串(基礎知識)第七周作業 一 1 、使用函數刪除字符串中的字符 輸入…

Vue實現組件props雙向綁定解決方案

注意: 子組件不能直接修改prop過來的數據,會報錯 方案一: 用data對象中創建一個props屬性的副本 watch props屬性 賦予data副本 來同步組件外對props的修改 watch data副本,emit一個函數 通知到組件外 HelloWorld組件代碼如下…

統計詞頻問題

adict{} xinput().lower() #把單詞大寫字母改為小寫字母 for i in x:if i in [,,.,"",",!]:xx[:x.index(i)]x[x.index(i)1:] #把句子中的非字母字符用切片操作刪掉 asetset(x.split( )) #集合的好處在于不重復 alstx.split( ) for n in aset:tempdict{n:alst.…

正則表達式常用函數

<?php //preg_match("正則表達式","字符串")用于在字符串中查找匹配項 $email "987044391qq.com"; if (preg_match("/^([a-zA-Z0-9])([.a-zA-Z0-9_-])*([.a-zA-Z0-9_-])([.a-zA-Z0-9_-])([.a-zA-Z0-9_-])$/",$email)){ echo 匹…

利用js的閉包原理做對象封裝及調用方法

創建一個js文件&#xff0c;名為testClosure.js&#xff1a; ? 1 2 3 4 5 6 7 8 9 (function () { function a() { alert(i am a); } outFunc function () { a(); } })(); 這里不論寫多少個function,a b c d ...外面都調用不到&#xff0c;包括這里面va…

Flask系列06--(中間件)Flask的特殊裝飾器 before_request,after_request, errorhandler

一.使用 Flask中的特殊裝飾器(中間件)方法常用的有三個 app.before_request # 在請求進入視圖函數之前app.after_request # 在請求結束視圖函數之后 響應返回客戶端之前app.errorhandler(404) # 重定義錯誤信息before_request def func():passafter_request def func(ret): # …

Flask 中內置的 Session

Flask中的Session非常的奇怪,他會將你的SessionID存放在客戶端的Cookie中,使用起來也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from flask import session app Flask(__name__) app.secret_key "DragonFire" secret_key 實際上是用來加密字符串的,如果…

CSS像素、物理像素、邏輯像素、設備像素比、PPI、Viewport

最近看了很多這方面的文章&#xff0c;能搜到的基本看了個遍&#xff0c;但感覺還是似懂非懂&#xff0c;知道這個東西&#xff0c;很難說出這是個什么東西&#xff0c;先整理一些概念&#xff0c;慢慢消化&#xff0c;以后慢慢探索其中的原因。 1、PX(CSS pixels) 1.1 定義 …

【轉】10條你不可不知的css規則

10條你不可不知的css規則 Posted on 2006-12-20 10:33 雨中太陽 閱讀(343) 評論(1) 編輯 收藏 &#xff1a;【譯】10條你不可不知的css規則正文&#xff1a; Published December 6th, 2004 in CssStaff Tags: No Tags. 原文地址&#xff1a;Ten CSS Tricks You May not Know k…

Python 面向對象【1】

對象 屬性 方法面向對象特征&#xff1a;分裝 繼承 多態【不同對象對同一方法響應不同行動】類定義class xxx:........類對象類對象支持兩種操作&#xff1a;屬性引用和實例化 屬性引用 使用和 Python 中所有的屬性引用一樣的標準語法&#xff1a;類對象名.屬性名 類對象創建…

【前端面試】HTML5+CSS3初級面試1

最近剛好在看前端的面試&#xff0c;把看到的內容總結一下&#xff0c;方便大家一起學習。 1、簡單說一下對HTML5CSS3的了解。 HTML5和CSS3不僅是兩項新的Web技術標準&#xff0c;而且代表了下一代HTML和CSS技術。其未來的發展前景已經可以預見&#xff0c;那就是HTML5必將被越…

福大軟工 · 第八次作業(課堂實戰)- 項目UML設計(團隊)

1、隊伍信息&#xff1a; 隊伍名稱&#xff1a;彳艮彳亍團隊 學號名本次作業博客鏈接031602219奇豪(隊長)https://www.cnblogs.com/S031602219/p/9822576.html041602209毓明http://www.cnblogs.com/mingsonic/p/9820702.html041602204水源http://www.cnblogs.com/littlenorthwe…

【轉發】實現yolo3模型訓練自己的數據集總結

原文鏈接&#xff1a;實現yolo3模型訓練自己的數據集總結 經過兩天的努力&#xff0c;借鑒網上眾多博客&#xff0c;在自己電腦上實現了使用yolo3模型訓練自己的數據集并進行測試圖片。本文主要是我根據下面參考文章一步步實施過程的總結&#xff0c;可能沒參考文章中那么詳細&…

詳解 vue-cli 的打包配置文件代碼(帶注釋)

一、前言 對于webpack基礎不好&#xff0c;node指令不通的童鞋。估計對自己搭建Vue、react腳手架是相當頭疼的&#xff0c;有種無從下手的感覺。然而&#xff0c;從頭看這2塊&#xff0c;耗時太長&#xff0c;而且說實話得練才行&#xff0c;不練練手看不明白。那大多數人就采取…

NoClassDefFoundError

技術之路最公平也最殘酷的原因是&#xff1a;沒有捷徑&#xff0c;需要日積月累的積累&#xff0c;以及對技術持久的熱情。NoClassDefFoundError這個錯誤一般就兩種情況&#xff1a;1、沒有引入相應的jar包2、兩個jar包中都有這個class&#xff0c;無法確認是引用的哪一個&…

【記錄一下】從0到1 我的python開發之路

請設計實現一個商城系統&#xff0c;商城主要提供兩個功能&#xff1a;商品管理、會員管理。商品管理&#xff1a;- 查看商品列表 - 根據關鍵字搜索指定商品 - 錄入商品會員管理&#xff1a;【無需開發&#xff0c;如選擇則提示此功能不可用&#xff0c;正在開發中&#xff0c;…

Python10/22--面向對象編程/類與對象/init函數

類&#xff1a; 語法: class關鍵字 類名# 類名規范 大寫開頭 駝峰命名法class SHOldboyStudent: # 描述該類對象的特征 school "上海Oldboy" name "矮根" age 68 gender "unknown" # 在定義階段 # 只要包含該類的py被…

Django Form和ModelForm組件

Form介紹 我們之前在HTML頁面中利用form表單向后端提交數據時&#xff0c;都會寫一些獲取用戶輸入的標簽并且用form標簽把它們包起來。 與此同時我們在好多場景下都需要對用戶的輸入做校驗&#xff0c;比如校驗用戶是否輸入&#xff0c;輸入的長度和格式等正不正確。如果用戶輸…