欧美日韩激情_美女国产一区_国产精品久久久久影院日本_69xxx在线

如何在Python怎么中使用heapq模塊-創新互聯

本篇文章為大家展示了如何在Python怎么中使用heapq模塊,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

成都創新互聯公司長期為上1000+客戶提供的網站建設服務,團隊從業經驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯網生態環境。為灤州企業提供專業的做網站、成都網站制作灤州網站改版等技術服務。擁有十多年豐富建站經驗和眾多成功案例,為您定制開發。

heapq 模塊實現了適用于Python列表的最小堆排序算法。

如何在Python怎么中使用heapq模塊

堆是一個樹狀的數據結構,其中的子節點都與父母排序順序關系。因為堆排序中的樹是滿二叉樹,因此可以用列表來表示樹的結構,使得元素 N 的子元素位于 2N + 1 和 2N + 2 的位置(對于從零開始的索引)。

本文內容將分為三個部分,第一個部分簡單介紹 heapq 模塊的使用;第二部分回顧堆排序算法;第三部分分析heapq中的實現。

heapq 的使用

創建堆有兩個基本的方法:heappush() 和 heapify(),取出堆頂元素用 heappop()。

heappush() 是用來向已有的堆中添加元素,一般從空列表開始構建:

import heapq

data = [97, 38, 27, 50, 76, 65, 49, 13]
heap = []

for n in data:
 heapq.heappush(heap, n)

print('pop:', heapq.heappop(heap)) # pop: 13
print(heap) # [27, 50, 38, 97, 76, 65, 49]

如果數據已經在列表中,則使用 heapify() 進行重排:

import heapq

data = [97, 38, 27, 50, 76, 65, 49, 13]

heapq.heapify(data)

print('pop:', heapq.heappop(data)) # pop: 13
print(data) # [27, 38, 49, 50, 76, 65, 97]

回顧堆排序算法

堆排序算法基本思想是:將無序序列建成一個堆,得到關鍵字最小(或大的記錄;輸出堆頂的最小 (大)值后,使剩余的 n-1 個元素 重又建成一個堆,則可得到n個元素的次小值 ;重復執行,得到一個有序序列,這個就是堆排序的過程。

堆排序需要解決兩個問題:

  • 如何由一個無序序列建立成一個堆?

  • 如何在輸出堆頂元素之后,調整剩余元素,使之成為一個新的堆?

  • 新添加元素和,如何調整堆?

先來看看第二個問題的解決方法。采用的方法叫“篩選”,當輸出堆頂元素之后,就將堆中最后一個元素代替之;然后將根結點值與左、右子樹的根結點值進行比較 ,并與其中小者進行交換;重復上述操作,直至葉子結點,將得到新的堆,稱這個從堆頂至葉子的調整過程為“篩選”。

如何在Python怎么中使用heapq模塊

如上圖所示,當堆頂 13 輸出后,將堆中末尾的 97 替代為堆頂,然后堆頂與它的子節點 38 和 27 中的小者交換;元素 97 在新的位置上在和它的子節點 65 和 49 中的小者交換;直到元素97成為葉節點,就得到了新的堆。這個過程也叫 下沉 。

讓堆中位置為 pos 元素進行下沉的如下:

def heapdown(heap, pos):
 endpos = len(heap)
 while pos < endpos:
 lchild = 2 * pos + 1
 rchild = 2 * pos + 2
 if lchild >= endpos: # 如果pos已經是葉節點,退出循環
  break
 childpos = lchild # 假設要交換的節點是左節點
 if rchild < endpos and heap[childpos] > heap[rchild]:
  childpos = rchild

 if heap[pos] < heap[childpos]: # 如果節點比子節點都小,退出循環
  break
 heap[pos], heap[childpos] = heap[childpos], heap[pos] # 交換
 pos = childpos

再來看看如何解決第三個問題:新添加元素和,如何調整堆?這個的方法正好與 下沉 相反,首先將新元素放置列表的最后,然后新元素與其父節點比較,若比父節點小,與父節點交換;重復過程直到比父節點大或到根節點。這個過程使得元素從底部不斷上升,從下至上恢復堆的順序,稱為 上浮 。

將位置為 pos 進行上浮的代碼為:

def heapup(heap, startpos, pos): # 如果是新增元素,startpos 傳入 0
 while pos > startpos:
 parentpos = (pos - 1) // 2
 if heap[pos] < heap[parentpos]:
  heap[pos], heap[parentpos] = heap[parentpos], heap[pos]
  pos = parentpos
 else:
  break

第一個問題:如何由一個無序序列建立成一個堆?從無序序列的第 n/2 個元素 (即此無序序列對應的完全二叉樹的最后一個非終端結點 )起 ,至第一個元素止,依次進行下沉:

如何在Python怎么中使用heapq模塊

for i in reversed(range(len(data) // 2)):
 heapdown(data, i)

heapq 源碼分析

添加新元素到堆中的 heappush() 函數:

def heappush(heap, item):
 """Push item onto heap, maintaining the heap invariant."""
 heap.append(item)
 _siftdown(heap, 0, len(heap)-1)

把目標元素放置列表最后,然后進行上浮。盡管它命名叫 down ,但這個過程是上浮的過程,這個命名也讓我困惑,后來我才知道它是因為元素的索引不斷減小,所以命名 down 。下沉的過程它也就命名為 up 了。

def _siftdown(heap, startpos, pos):
 newitem = heap[pos]
 # Follow the path to the root, moving parents down until finding a place
 # newitem fits.
 while pos > startpos:
  parentpos = (pos - 1) >> 1
  parent = heap[parentpos]
  if newitem < parent:
   heap[pos] = parent
   pos = parentpos
   continue
  break
 heap[pos] = newitem

一樣是通過 newitem 不斷與父節點比較。不一樣的是這里缺少了元素交換的過程,而是計算出新元素最后所在的位置 pos 并進行的賦值。顯然這是優化后的代碼,減少了不斷交換元素的冗余過程。

再來看看輸出堆頂元素的函數 heappop():

def heappop(heap):
 """Pop the smallest item off the heap, maintaining the heap invariant."""
 lastelt = heap.pop() # raises appropriate IndexError if heap is empty
 if heap:
  returnitem = heap[0]
  heap[0] = lastelt
  _siftup(heap, 0)
  return returnitem
 return lastelt

通過 heap.pop() 獲得列表中的最后一個元素,然后替換為堆頂 heap[0] = lastelt ,再進行下沉:

def _siftup(heap, pos):
 endpos = len(heap)
 startpos = pos
 newitem = heap[pos]
 # Bubble up the smaller child until hitting a leaf.
 childpos = 2*pos + 1 # 左節點,默認替換左節點
 while childpos < endpos:
  # Set childpos to index of smaller child.
  rightpos = childpos + 1 # 右節點
  if rightpos < endpos and not heap[childpos] < heap[rightpos]:
   childpos = rightpos # 當右節點比較小時,應交換的是右節點
  # Move the smaller child up.
  heap[pos] = heap[childpos]
  pos = childpos
  childpos = 2*pos + 1
 # The leaf at pos is empty now. Put newitem there, and bubble it up
 # to its final resting place (by sifting its parents down).
 heap[pos] = newitem
 _siftdown(heap, startpos, pos)

這邊的代碼將準備要下沉的元素視為新元素 newitem ,將其當前的位置 pos 視為空位置,由其子節點中的小者進行取代,反復如此,最后會在葉節點留出一個位置,這個位置放入 newitem ,再讓新元素進行上浮。

再來看看讓無序數列重排成堆的 heapify() 函數:

def heapify(x):
 """Transform list into a heap, in-place, in O(len(x)) time."""
 n = len(x)
 for i in reversed(range(n//2)):
  _siftup(x, i)

上述內容就是如何在Python怎么中使用heapq模塊,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注創新互聯行業資訊頻道。

文章標題:如何在Python怎么中使用heapq模塊-創新互聯
瀏覽地址:http://www.kartarina.com/article20/cecico.html

成都網站建設公司_創新互聯,為您提供營銷型網站建設移動網站建設企業網站制作動態網站關鍵詞優化ChatGPT

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

手機網站建設
欧美日韩激情_美女国产一区_国产精品久久久久影院日本_69xxx在线
高清在线观看日韩| 欧美国产一区二区| 在线观看日韩高清av| 国产91丝袜在线18| 国产电影一区二区三区| 精品无码三级在线观看视频| 男人的天堂亚洲一区| 日韩av电影天堂| 蜜臀久久久久久久| 天堂在线一区二区| 久久99国产精品久久99果冻传媒| 蜜桃视频一区二区三区在线观看| 蜜桃av一区二区三区电影| 麻豆一区二区在线| 国产一区二区美女| www.成人在线| 在线欧美日韩国产| 91精品国产综合久久久蜜臀粉嫩| 91精品国产免费| 欧美成人精品3d动漫h| 久久精品日产第一区二区三区高清版| 国产欧美精品国产国产专区| 中文字幕亚洲成人| 亚洲大片在线观看| 国产一区二三区好的| www.视频一区| 777a∨成人精品桃花网| 99国产精品久久久久久久久久| 美国毛片一区二区| 精品亚洲免费视频| 懂色av一区二区三区免费观看| 不卡电影免费在线播放一区| 欧美综合欧美视频| 欧美成人性福生活免费看| 国产日本亚洲高清| 亚洲国产日产av| 国产一区二区伦理| 在线观看免费视频综合| 精品国产成人在线影院| 亚洲免费三区一区二区| 美国欧美日韩国产在线播放| 99国产精品久久久久久久久久| 欧美中文字幕一区二区三区亚洲| 欧美videossexotv100| 亚洲免费av高清| 国产福利91精品一区二区三区| 在线亚洲一区二区| 国产午夜精品久久久久久免费视| 亚洲一区二区三区影院| 成人午夜精品在线| 日韩美女天天操| 亚洲一区二区三区小说| 波多野结衣一区二区三区| 日韩欧美国产午夜精品| 亚洲成人自拍偷拍| 91免费看片在线观看| 国产亚洲综合在线| 韩国精品主播一区二区在线观看 | 日韩无一区二区| 一区二区三区不卡视频在线观看| 国产麻豆精品在线| 日韩欧美色综合网站| 亚洲一区二区av在线| 色美美综合视频| 国产精品欧美久久久久无广告 | 中文字幕亚洲成人| 成人免费视频一区| 久久免费精品国产久精品久久久久| 偷偷要91色婷婷| 欧美探花视频资源| 亚洲激情欧美激情| 91黄色激情网站| 亚洲女爱视频在线| 在线看不卡av| 亚洲mv大片欧洲mv大片精品| 色欧美片视频在线观看在线视频| 国产精品你懂的| av网站一区二区三区| 亚洲欧美在线另类| 色婷婷亚洲精品| 亚洲国产精品久久久久秋霞影院| 欧美综合久久久| 日本三级亚洲精品| wwwwxxxxx欧美| 92精品国产成人观看免费| 国产网站一区二区| av不卡在线观看| 亚洲精品一卡二卡| 欧美日本一区二区三区| 秋霞午夜av一区二区三区| 日韩精品一区二区三区视频 | 成人av在线影院| 中文字幕在线一区二区三区| av激情成人网| 亚洲午夜成aⅴ人片| 911国产精品| 国产乱子伦视频一区二区三区 | 国产精品自拍网站| 国产精品久久久久久久久久免费看 | 色综合久久中文综合久久97| 亚洲午夜在线电影| 日韩精品一区二区三区中文不卡 | 一色屋精品亚洲香蕉网站| 欧美伊人久久大香线蕉综合69| 日韩影院免费视频| 国产欧美日韩不卡免费| 欧美这里有精品| 激情综合网激情| 亚洲日本va午夜在线电影| 538prom精品视频线放| 国产成人在线观看| 亚洲午夜激情av| 国产日韩高清在线| 欧美群妇大交群中文字幕| 国产精品18久久久久久vr| 人禽交欧美网站| 欧美视频日韩视频在线观看| 婷婷综合另类小说色区| 精品久久久久99| 日本韩国视频一区二区| 国产一区欧美二区| 五月天丁香久久| 综合中文字幕亚洲| 久久综合久色欧美综合狠狠| 日本韩国一区二区三区视频| 国产精品激情偷乱一区二区∴| 国产高清亚洲一区| 香蕉av福利精品导航| 一区二区三区中文字幕电影| 91精品欧美久久久久久动漫| 成人蜜臀av电影| 韩国成人在线视频| 狂野欧美性猛交blacked| 亚洲小说欧美激情另类| 日韩毛片视频在线看| 日韩免费观看高清完整版在线观看| 色婷婷精品大在线视频| 成熟亚洲日本毛茸茸凸凹| 精一区二区三区| 午夜精品免费在线观看| 伊人色综合久久天天| 亚洲视频香蕉人妖| 亚洲视频在线一区二区| 日本一区二区久久| 国产精品丝袜黑色高跟| 国产日韩欧美在线一区| 久久一二三国产| 国产午夜亚洲精品不卡| 久久久一区二区| 国产色产综合产在线视频| 久久―日本道色综合久久| 欧美精品一区二区三| 欧美大片免费久久精品三p| 欧美一区二区三区四区五区| 4438成人网| 宅男噜噜噜66一区二区66| 3751色影院一区二区三区| 欧美唯美清纯偷拍| 欧美人伦禁忌dvd放荡欲情| 欧美精品1区2区3区| 欧美一级二级三级蜜桃| 精品国产一区二区精华| 久久香蕉国产线看观看99| 国产午夜精品久久久久久免费视| 国产视频一区二区在线| 中文字幕一区二区三中文字幕| 亚洲色图制服诱惑| 日欧美一区二区| 激情欧美一区二区三区在线观看| 国产一区二区美女诱惑| 99久久伊人网影院| 欧美日韩一区二区三区在线看| 日韩一区二区免费电影| 久久精品视频一区| 亚洲精品成a人| 韩国视频一区二区| 成人午夜在线播放| 精品视频123区在线观看| 日韩女优毛片在线| 国产精品色呦呦| 婷婷夜色潮精品综合在线| 国内久久婷婷综合| 色老综合老女人久久久| 精品乱人伦小说| 日韩美女久久久| 久久99精品久久只有精品| 99久久精品免费看国产| 日韩一区国产二区欧美三区| 国产精品污污网站在线观看| 亚洲chinese男男1069| 国产mv日韩mv欧美| 7777精品伊人久久久大香线蕉最新版| 久久欧美一区二区| 亚洲成a人v欧美综合天堂下载| 国产精品1区二区.| 欧美一区二区三区四区久久| 专区另类欧美日韩| 国产一区二区三区久久久| 欧美日产国产精品| 综合自拍亚洲综合图不卡区|