精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Python 高級算法和數據結構:集合的快速查詢與合并

開發 后端 算法
在代碼設計中時常面對這樣的場景,給定兩個元素,我們需要快速判斷他們是否屬于同一個集合,同時不同的集合在需要時還能快速合并為一個集合,例如我們要開發一個社交應用,那么判斷兩個用戶是否是朋友關系,或者兩人是否屬于同一個群就需要用到我們現在提到的功能。

在代碼設計中時常面對這樣的場景,給定兩個元素,我們需要快速判斷他們是否屬于同一個集合,同時不同的集合在需要時還能快速合并為一個集合,例如我們要開發一個社交應用,那么判斷兩個用戶是否是朋友關系,或者兩人是否屬于同一個群就需要用到我們現在提到的功能。

這些功能看似簡單,但有個難點在于你要處理的“足夠快”,假設a,b兩個元素分別屬于集合A,B,判斷它們是否屬于同一個集合的直接做法就是遍歷集合A中所有元素,看看是否能找到b,如果集合A中包含n個元素,那么該做法的時間復雜度就是O(n),當集合元素很多,而且判斷的次數也很多時,這樣的做法效率就會很低,本節我們要看看能不能找到次線性的算法。

我們先看復雜度為O(n)的算法邏輯,假設我們有6個元素,編號分別為0到6,我們可以使用隊列來模擬集合,屬于同一個集合的元素就存儲在同一個隊列中,然后每個元素通過哈希表映射到隊列頭,如下圖所示:

在這種數據結構下,查詢兩個元素是否屬于同一個集合,那么只要通過哈希表找到各自元素所在隊列的頭部,判斷頭部是否一致即可,我們用areDisjoint(x,y)來表示兩個元素是否屬于一個集合,那么在當前數據結構下areDisjoint的時間復雜度是O(1)。

如果要合并兩個元素所在集合,我們用merge(x,y)來表示,那么在當前結構下,我們只要找到x和y對應的隊列頭部,然后從x所在隊列的頭部遍歷到最后一個元素,然后將最后一個元素的next指針執行y所在的隊列頭部,如下圖所示:

同時我們還需要做一個操作,那就是修改第二個集合中每個元素映射的隊列頭部,因此在當前結構下,merge(x,y)對應時間復雜度為O(n),因為從隊列頭遍歷到末尾是O(n),同時遍歷y所在集合每個元素,修改他們映射的隊列頭,時間復雜度也是O(n)。

現在問題是我們能否將合并所需要的時間進行優化。我們注意到合并時有兩個步驟很耗時,一是從隊列走到隊尾,二是修改第二個集合中每個元素指向的隊列頭。所以耗時其實是因為我們使用隊列來表示集合所導致。為了優化時間,我們將隊列換成多叉樹,如下圖所示:

此時我們不再使用哈希表來將元素映射到隊列頭部,而是將同一個集合的元素安插到同一個多叉樹中,要判斷兩個元素是否屬于同一集合,我們只要沿著元素的父節點指針往上走一直找到樹的根節點,如果找到相同的根節點,那么兩個元素就屬于同一集合,對于排序二叉樹而言,樹的高度為O(lg(n)),n是樹的節點數,于是判斷兩個元素是否屬于同一集合所需時間復雜度為O(lg(n))。

當需要合并兩個元素對于的集合時,我們分別找到兩個元素對于的根節點,然后將高度較低的那棵樹的根節點作為高度較高那棵樹的子節點,這個處理對效率很重要,后面我們會進一步研究,樹合并的情形如下圖所示:

下面我們先看看代碼實現:

 

  1. # This is a sample Python script. 
  2.  
  3. # Press ⌃R to execute it or replace it with your code. 
  4. # Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings. 
  5.  
  6. class Element: 
  7.     def __init__(self, val : int): 
  8.         self.val = val 
  9.         self.parent = self #元素在創建時自己形成一個單獨集合,因此父節點指向自己 
  10.     def value(self): 
  11.         return self.val 
  12.     def parent(self): 
  13.         return self.parent 
  14.     def set_parent(self, parent): 
  15.         assert parent is not None 
  16.         self.parent = parent 
  17.  
  18. class DisjontSet: 
  19.     def __init__(self): 
  20.         self.hash_map = {} 
  21.     def add(self, elem : Element): 
  22.         assert elem is not None 
  23.         if elem.value() in self.hash_map: 
  24.             return False 
  25.         self.hash_map[elem.value()] = elem 
  26.         return True 
  27.     def find_partition(self, elem : Element): 
  28.         #返回元素所在集合的根節點 
  29.         assert elem is not None or elem.value() in self.hash_map 
  30.         parent = elem.parent() 
  31.         if parent != elem: #遞歸查找根節點,樹的高度為lg(n),所以這里查找的時間復雜度為lg(n) 
  32.             parent = self.find_partition(parent) 
  33.         return parent 
  34.  
  35.     def are_disjoint(self, elem1 : Element, elem2 : Element): 
  36.         #判斷兩個元素是否屬于同一集合只要判斷他們再哈希表中映射的根節點是否同一個 
  37.         root1 = self.find_partition(elem1) 
  38.         root2 = self.find_partition(elem2) 
  39.         return root1 is not root2 
  40.  
  41.     def merge(self, elem1 : Element, elem2 : Element): 
  42.         root1 = self.find_partition(elem1) 
  43.         root2 = self.find_partition(elem2) 
  44.         if root1 is root2: 
  45.             #兩個元素屬于同一個集合 
  46.             return False 
  47.         root2.setParent(root1) 
  48.         self.hash_map[root2.value()] = root1 #設置root2對應的父節點 
  49.  
  50. # Press the green button in the gutter to run the script. 
  51. if __name__ == '__main__'
  52.  
  53. # See PyCharm help at https://www.jetbrains.com/help/pycharm/ 

 

由于我們將集合的表示從隊列改為了多叉樹,因此集合的查找與合并對應復雜度為O(lg(n)),現在問題是我們能否繼續改進效率。當前merge函數耗時在于我們要通過parent指針一直爬到根節點,如果能讓parent指針直接指向根節點那么不就省卻向上爬的時間開銷嗎,這種直接將下層節點父指針直接指向根節點的辦法叫路徑壓縮,如下圖所示:

從上圖看到,節點6,8的父節點原來是9,它所在集合的根節點是1,于是我們直接將原來指向9的指針直接指向根節點1,這樣以后在合并或查詢集合時我們就可以省掉向上爬的時間開銷。還有一個問題在上面代碼中兩棵樹合并問題,我們僅僅是把root2的父指針指向root1,這么做會存在合并后樹不平衡問題,也就是合并后的左右子樹高度可能相差較大,這種情況也會對效率產生不利影響,如下圖所示:

可以看到右下角合并后左右子樹高度差異大,于是節點,6,8找到根節點0所需的時間就要比2,3,4要多,但形成右上角的情況時,葉子節點6,8和2,3,4找到根節點的時間就差不多,這樣就有利于效率的提高,所以我們還需要記錄下樹的高度,在合并時要將高度小的樹合向高度高的樹,因此代碼修改如下:

  1. class Element: 
  2.     def __init__(self, val : int): 
  3.         self.val = val 
  4.         self.parent = self #元素在創建時自己形成一個單獨集合,因此父節點指向自己 
  5.         self.rank = 1 #表示樹的高度 
  6.     def value(self): 
  7.         return self.val 
  8.     def parent(self): 
  9.         return self.parent 
  10.     def set_parent(self, parent): 
  11.         assert parent is not None 
  12.         self.parent = parent 
  13.     def get_rank(self): 
  14.         return self.rank  
  15.     def set_rank(self, rank): 
  16.         assert rank > 1 
  17.         self.rank = rank 

然后我們需要修改find_partition的做法

  1. def find_partition(self, elem : Element): 
  2.     #返回元素所在集合的根節點 
  3.     assert elem is not None or elem.value() in self.hash_map 
  4.     parent = elem.parent() 
  5.     if parent is elem: #已經是根節點 
  6.         return elem  
  7.     parent = self.find_partition(elem) #獲得集合的根節點 
  8.     elem.set_parent(parent) #路徑壓縮直接指向根節點 
  9.     return parent #返回根節點 

注意到find_partion的實現中有遞歸過程,如果當前節點不是根節點,那么遞歸的查詢根節點,然后把當前節點的parent指針直接指向根節點,我們看到這步修改所需的時間復雜度跟原來一樣都是lg(n)。

接下來我們要修改merge的實現:

  1. def merge(self, elem1 : Element, elem2 : Element): 
  2.         root1 = self.find_partition(elem1) 
  3.         root2 = self.find_partition(elem2) 
  4.         if root1 is root2:  # 兩個元素屬于同一個集合 
  5.             return False 
  6.         new_rank = root1.get_rank() + root2.get_rank() 
  7.         if root1.get_rank() >= root2.get_rank():  # 根據樹的高度來決定合并方向 
  8.             root2.set_parent(root1) 
  9.             root1.set_rank(new_rank) 
  10.         else
  11.             root1.set_parent(root2) 
  12.             root2.set_rank(new_rank) 
  13.         return True 

這種改進后,在m次指向find_partion和merge調用時所需要的時間是O(m),也就是說在改進后,當大量調用find_partion和merge時,這些調用的平均耗時降到了O(1),也就是說路徑壓縮后,其效果在大批量的調用查找集合和合并集合操作時能出現非常顯著的效率提升,其對應的數學證明非常負責,我們暫時忽略調。我們可能對這里的效率提升感受不到,但想想微信中對兩個人是否屬于同一個群的調用一天至少也有千萬乃至上億次吧,因此這里的改進能大大的改進服務器的處理效率。

完整代碼在這里

https://github.com/wycl16514/python_disjoint_set.git

 

責任編輯:武曉燕 來源: Coding迪斯尼
相關推薦

2023-09-15 10:33:41

算法數據結構

2023-03-07 08:02:07

數據結構算法數列

2021-12-08 11:31:43

數據結構算法合并區間

2020-08-12 08:30:20

數據結構算法

2021-07-16 04:57:45

Go算法結構

2019-06-10 14:45:26

面試數據結構算法

2020-10-21 14:57:04

數據結構算法圖形

2023-09-25 12:23:18

Python

2023-10-26 09:17:48

算法編程

2023-03-08 08:03:09

數據結構算法歸并排序

2023-10-27 07:04:20

2023-04-27 09:13:20

排序算法數據結構

2023-03-02 08:15:13

2023-03-10 08:07:39

數據結構算法計數排序

2021-09-12 17:31:17

Python數據結構

2022-02-22 15:27:46

數據結構容器算法

2021-01-28 07:33:34

JavaScript鏈表數據

2023-02-08 07:52:36

跳躍表數據結構

2023-10-30 08:31:42

數據結構算法

2023-11-06 06:43:23

單鏈表查詢數據結構
點贊
收藏

51CTO技術棧公眾號

欧美 国产 日本| 国产成人免费观看| 四虎884aa成人精品| 免费一级欧美片在线观看网站| 亚洲午夜激情网站| 欧洲一区二区在线| 精品人妻一区二区三区换脸明星| 91久久在线| 中文字幕亚洲一区二区三区五十路| aaa一级黄色片| 性xxxxfreexxxxx欧美丶| 国产精品伦一区二区三级视频| 成人在线观看av| 少妇无套内谢久久久久| 欧美网站在线| 夜夜躁日日躁狠狠久久88av| 动漫美女无遮挡免费| 69堂精品视频在线播放| 亚洲成年人网站在线观看| 一区二区三区欧美在线| 亚洲欧美一区二区三| 精品一区二区三区av| 国产91精品黑色丝袜高跟鞋| 中文字幕人妻一区二| 久草精品在线| 精品sm在线观看| 男女视频在线观看网站| 国产精品亚洲一区二区三区在线观看 | 黄色成人av在线| 国产人妻互换一区二区| 成人动漫在线播放| 91蜜桃网址入口| 成人动漫在线视频| 国产欧美熟妇另类久久久| 老牛国产精品一区的观看方式 | 久久人体大尺度| 亚洲va天堂va国产va久| 妺妺窝人体色www看人体| 在线观看的av| 国产三级久久久| 久久久影院一区二区三区| 国产91免费看| 成人性生交大片| 99r国产精品视频| 国产女人18毛片水18精| 九九久久精品视频| 国产精品视频免费在线观看| 无码无套少妇毛多18pxxxx| 91久久亚洲| 97婷婷涩涩精品一区| 国产午夜精品无码| 一区在线观看| 91po在线观看91精品国产性色| 国产在线观看免费视频今夜| 国产精品啊啊啊| 久久久久久久久久久免费 | 亚洲福利在线看| 毛茸茸free性熟hd| 欧美日韩一本| 精品一区二区三区四区| 亚洲av无码国产精品麻豆天美| 婷婷精品在线观看| 亚洲午夜av电影| 99自拍偷拍视频| 亚洲国产精品综合久久久| 久久国产精品电影| 精品一区二区三区四| 狠久久av成人天堂| 欧美怡红院视频一区二区三区| 欧美一级特黄视频| 日韩精品一级中文字幕精品视频免费观看 | 亚洲欧美精品在线| 在线免费观看麻豆| 成人av国产| 美女视频黄免费的亚洲男人天堂| 久久久国产精品人人片| 一区二区高清| 国产精品第二页| 国产美女无遮挡永久免费| 国产99精品国产| 麻豆成人在线播放| 高清美女视频一区| 亚洲免费观看在线视频| 日本a在线免费观看| 色在线中文字幕| 欧美日韩一区二区三区四区| 免费人成视频在线播放| 色狠狠久久av综合| 日韩在线免费观看视频| 国产一级二级三级视频| 肉肉av福利一精品导航| 96pao国产成视频永久免费| 免费观看毛片网站| 国产精品人妖ts系列视频| 国产精品av免费观看| 制服丝袜专区在线| 91精品国产入口| 成年人网站免费看| 91不卡在线观看| 欧美亚洲免费电影| 国产人妖一区二区三区| 91美女福利视频| 天天做天天爱天天高潮| 精品捆绑调教一区二区三区| 欧美日韩国产综合一区二区| 在线精品视频播放| 久久亚洲在线| 欧美夜福利tv在线| a天堂在线视频| 国产日产欧美一区二区三区| 久久男人资源站| 成人深夜福利| 亚洲欧美激情另类校园| 精品在线视频免费| 经典三级在线一区| 日韩免费中文专区| 国产网站在线| 精品伦理精品一区| 成人免费精品动漫网站| 久久久夜精品| 国产一区二区在线网站| 18网站在线观看| 欧美性xxxxxxxx| 欧美一区二区三区成人精品| 国产一区二区三区四区三区四| 国产精品精品一区二区三区午夜版 | 韩国午夜理伦三级不卡影院| 日韩中文字幕一区二区| 亚洲v.com| 亚洲成人动漫在线播放| 五月天激情丁香| 久久国内精品视频| 日韩精品欧美专区| 久久人体大尺度| 日韩大片免费观看视频播放| 久久人人爽人人爽人人| 国产精品资源在线看| 秋霞在线一区二区| 丰满少妇一区| 在线看福利67194| 懂色av中文字幕| 国产亚洲一区字幕| av无码精品一区二区三区| 神马香蕉久久| 26uuu另类亚洲欧美日本老年| 亚洲精品.www| 香港成人在线视频| 国产精品无码专区| 国产一区二区高清| 欧美xxxx黑人又粗又长密月| 国产精品一区二区av影院萌芽| 亚洲精品动漫100p| 国产日产精品一区二区三区| 久久一夜天堂av一区二区三区| 国产v片免费观看| 天海翼精品一区二区三区| 2019精品视频| 国产主播福利在线| 欧美日韩激情在线| 婷婷久久综合网| 成人免费观看男女羞羞视频| 久久国产精品网| 亚洲第一福利社区| 国产精品jizz在线观看麻豆| 97视频精彩视频在线观看| 欧美日韩黄色一区二区| 永久免费看黄网站| 91最新地址在线播放| www.国产区| 99久久综合狠狠综合久久aⅴ| 成人有码在线播放| 国产在线xxx| 亚洲少妇激情视频| 国产剧情久久久| 亚洲电影第三页| 亚洲第一香蕉网| 麻豆国产一区二区| 成人精品视频在线播放| 视频一区中文| 999热视频| 色一区二区三区| 精品国产一区av| 欧美熟妇另类久久久久久不卡| 欧美日韩人人澡狠狠躁视频| 少妇一级黄色片| 国产**成人网毛片九色 | 激情成人开心网| 天海翼精品一区二区三区| 国产色视频一区| av白虎一区| 丝袜美腿亚洲一区二区| 高h调教冰块play男男双性文| 在线观看亚洲一区| 久久久91视频| 欧美国产国产综合| 成人做爰69片免费| 蜜桃91丨九色丨蝌蚪91桃色| 免费在线看黄色片| 日韩一区二区在线免费| 国产一区免费视频| 国产一区二区三区视频在线| 4438全国成人免费| 伊人精品影院| 中文字幕亚洲无线码a| 亚洲人视频在线观看| 4438成人网| 免费在线观看av的网站| 亚洲成人tv网| 美女福利视频在线观看| 欧美国产激情二区三区| 37p粉嫩大胆色噜噜噜| 国产999精品久久久久久绿帽| 视频二区在线播放| 亚洲女同在线| 亚洲精品久久久久久久蜜桃臀| 久久视频精品| 日韩欧美一区二区视频在线播放| 国产+成+人+亚洲欧洲在线| 成人做爰www免费看视频网站| 3d欧美精品动漫xxxx无尽| 午夜欧美不卡精品aaaaa| 主播国产精品| 日韩视频一区在线| 亚洲人在线观看视频| 亚洲电影免费观看| 性少妇videosexfreexxx片| 在线播放一区二区三区| 国产精品尤物视频| 色天天综合色天天久久| 欧美一区二区三区四| 亚洲高清在线视频| 久久久无码精品亚洲国产| 亚洲免费三区一区二区| 国产日产精品一区二区三区的介绍| 国产欧美日韩综合| 国产aⅴ激情无码久久久无码| 91丝袜美腿高跟国产极品老师| 美女伦理水蜜桃4| 成人h动漫精品| 免费看黄色片的网站| 成人性视频网站| 国产黄色三级网站| 久久亚洲综合色| 国产高清自拍视频| 久久综合精品国产一区二区三区 | 中文字幕中文字幕在线一区| 91成人精品一区二区| 亚洲国产成人自拍| 亚洲欧美另类日本| 中文字幕一区二区在线观看| 亚洲精品国产精品乱码在线观看| 国产精品久久夜| 一级片一级片一级片| 樱花影视一区二区| 久久精品这里有| 午夜电影网亚洲视频| 亚洲欧美自拍视频| 欧洲视频一区二区| 国产精品视频a| 欧美一区二区啪啪| 亚洲乱码在线观看| 亚洲精品视频网上网址在线观看| 玖玖综合伊人| 久久国内精品一国内精品| 最爽无遮挡行房视频在线| 91高清在线免费观看| 久久野战av| 91欧美激情另类亚洲| 成人动漫视频| 日韩偷拍一区二区| 久久久久久久久久久久久久| 国产情侣第一页| 麻豆精品网站| а 天堂 在线| 99精品国产99久久久久久白柏| 日本少妇高潮喷水xxxxxxx| 亚洲欧美综合另类在线卡通| 欧美日韩在线视频免费| 高跟丝袜一区二区三区| 亚洲天堂视频网| 精品国产伦一区二区三区观看体验| 日本一本草久在线中文| 久久精品久久久久久国产 免费| 高清电影在线观看免费| 日本精品久久电影| 亚洲精品毛片| 精品一区二区三区国产| 国产高清一区| www.浪潮av.com| 国产一区欧美二区| www.色多多| 一区二区三区四区乱视频| www.色国产| 精品捆绑美女sm三区| 视频一区二区三区不卡| 1769国内精品视频在线播放| 精品国产不卡一区二区| 日本午夜精品一区二区| 在线看片一区| 色综合五月婷婷| 国产日韩精品视频一区| 久久高清免费视频| 欧美一区二区三区系列电影| 免费一级毛片在线观看| 久久久在线视频| 国产一区二区三区视频在线| 五月天综合网| 久久久亚洲一区| 黄色网址在线视频| 一区二区三区四区不卡视频| 中文在线最新版天堂| 精品视频—区二区三区免费| 性欧美1819sex性高清大胸| 国产精品午夜视频| 国产亚洲一区| 六月丁香婷婷激情| 成人激情免费网站| 清纯粉嫩极品夜夜嗨av| 欧美日韩国产精选| 国产视频三级在线观看播放| 97视频免费观看| 成人福利免费在线观看| 中文字幕精品在线播放| 六月婷婷色综合| 日韩影视一区二区三区| 色综合一个色综合| 午夜在线视频观看| 97色在线观看免费视频| 国产三级精品三级在线观看国产| 一道本在线观看视频| 极品美女销魂一区二区三区| 香蕉久久久久久久| 欧美色视频一区| 秋霞午夜理伦电影在线观看| 国产精品欧美一区二区三区奶水| 精品久久国产| 欧美激情精品久久久久久小说| 2023国产精品自拍| 伊人手机在线视频| 国产亚洲精品va在线观看| 26uuu亚洲电影| 欧美日韩亚洲一区二区三区四区| 亚洲在线成人| 国产三级av在线播放 | 国产男女裸体做爰爽爽| 久久精品视频在线| 另类视频一区二区三区| 穿情趣内衣被c到高潮视频| 国产成人在线免费| 九九在线观看视频| 日韩av一卡二卡| 97成人资源| 亚洲精品不卡| 国产麻豆精品久久一二三| 午夜写真片福利电影网| 亚洲第一区在线观看| 无码小电影在线观看网站免费| 久久久久久欧美精品色一二三四| 亚洲在线国产日韩欧美| 熟女少妇内射日韩亚洲| 欧美日本精品一区二区三区| 成人黄色网址| 久久99影院| 奇米色一区二区三区四区| 2025国产精品自拍| 亚洲成人三级在线| 爱情电影社保片一区| 亚洲视频电影| 国产成人在线视频网址| 欧美国产成人精品一区二区三区| 中文字幕亚洲激情| 日本精品在线观看| 免费看日本毛片| 国产精品美女一区二区在线观看| 国产激情视频在线播放| 26uuu亚洲伊人春色| 91综合在线| 波多野结衣加勒比| 欧美午夜宅男影院| 视频在线观看入口黄最新永久免费国产 | 亚洲欧美成人一区二区三区| 日韩在线观看视频一区| 国产精品精品久久久久久| 欧美体内she精视频在线观看| 国产av自拍一区| 日韩天堂在线观看| 欧美电影免费观看| 欧美少妇一区二区三区| 2023国产精品自拍| www天堂在线| 国产精品福利无圣光在线一区| 欧美成人久久| 日本爱爱爱视频| 亚洲国产婷婷香蕉久久久久久| 国产激情欧美| 久久久久狠狠高潮亚洲精品| 一区二区三区不卡在线观看| 第一视频专区在线| 精品高清视频| 国产老妇另类xxxxx|