python下實(shí)現(xiàn)二叉堆以及堆排序的示例
堆是一種特殊的樹(shù)形結(jié)構(gòu), 堆中的數(shù)據(jù)存儲(chǔ)滿足一定的堆序。堆排序是一種選擇排序, 其算法復(fù)雜度, 時(shí)間復(fù)雜度相對(duì)于其他的排序算法都有很大的優(yōu)勢(shì)。
堆分為大頭堆和小頭堆, 正如其名, 大頭堆的第一個(gè)元素是最大的, 每個(gè)有子結(jié)點(diǎn)的父結(jié)點(diǎn), 其數(shù)據(jù)值都比其子結(jié)點(diǎn)的值要大。小頭堆則相反。
我大概講解下建一個(gè)樹(shù)形堆的算法過(guò)程:
找到N/2 位置的數(shù)組數(shù)據(jù), 從這個(gè)位置開(kāi)始, 找到該節(jié)點(diǎn)的左子結(jié)點(diǎn)的索引, 先比較這個(gè)結(jié)點(diǎn)的下的子結(jié)點(diǎn), 找到最大的那個(gè), 將最大的子結(jié)點(diǎn)的索引賦值給左子結(jié)點(diǎn), 然后將最大的子結(jié)點(diǎn)和父結(jié)點(diǎn)進(jìn)行對(duì)比, 如果比父結(jié)點(diǎn)大, 與父節(jié)點(diǎn)交換數(shù)據(jù)。當(dāng)然, 我只是大概說(shuō)了下實(shí)現(xiàn), 在此過(guò)程中, 還需要考慮結(jié)點(diǎn)不存在的情況。
看下代碼:
# 構(gòu)建二叉堆 def binaryHeap(arr, lenth, m): temp = arr[m] # 當(dāng)前結(jié)點(diǎn)的值 while(2*m+1 < lenth): lchild = 2*m+1 if lchild != lenth - 1 and arr[lchild] < arr[lchild + 1]: lchild = lchild + 1 if temp < arr[lchild]: arr[m] = arr[lchild] else: break m = lchild arr[m] = temp def heapsort(arr, length): i = int(len(arr)/2) while(i >= 0): binaryHeap(arr, len(arr), i) i = i - 1 print("二叉堆的物理順序?yàn)?") print(arr) # 輸出二叉堆的物理順序 if __name__ == '__main__': arr = [2, 87, 39, 49, 34, 62, 53, 6, 44, 98] heapsort(arr, len(arr))
堆排序過(guò)程就是依次將最后的結(jié)點(diǎn)與首個(gè)節(jié)點(diǎn)進(jìn)行對(duì)比交換:
# 構(gòu)建二叉堆 def binaryHeap(arr, lenth, m): temp = arr[m] # 當(dāng)前結(jié)點(diǎn)的值 while(2*m+1 < lenth): lchild = 2*m+1 if lchild != lenth - 1 and arr[lchild] < arr[lchild + 1]: lchild = lchild + 1 if temp < arr[lchild]: arr[m] = arr[lchild] else: break m = lchild arr[m] = temp def heapsort(arr, length): i = int(len(arr)/2) while(i >= 0): binaryHeap(arr, len(arr), i) i = i - 1 print("二叉堆的物理順序?yàn)?") print(arr) # 輸出二叉堆的物理順序 i = length-1 while(i > 0): arr[i], arr[0] = arr[0], arr[i] # 變量交換 binaryHeap(arr, i, 0) i = i - 1560 def pop(arr): first = arr.pop(0) return first if __name__ == '__main__': arr = [2, 87, 39, 49, 34, 62, 53, 6, 44, 98] heapsort(arr, len(arr)) print("堆排序后的物理順序") print(arr) # 輸出經(jīng)過(guò)堆排序之后的物理順序 data = pop(arr) print(data) print(arr)
python封裝了一個(gè)堆模塊, 我們使用該模塊可以很高效的實(shí)現(xiàn)一個(gè)優(yōu)先隊(duì)列
import heapq class Item: def __init__(self, name): self.name = name def __repr__(self): return 'Item({!r})'.format(self.name) class PriorityQueue: def __init__(self): self._queue = [] self._index = 0 def push(self, item, priority): heapq.heappush(self._queue, (-priority, self._index, item)) # 存入一個(gè)三元組 self._index += 1 def pop(self): return heapq.heappop(self._queue)[-1] # 逆序輸出 if __name__ == '__main__': p = PriorityQueue() p.push(Item('foo'), 1) p.push(Item('bar'), 5) p.push(Item('spam'), 4) p.push(Item('grok'), 1) print(p.pop()) print(p.pop())
具體請(qǐng)看heapq官網(wǎng)
以上這篇python下實(shí)現(xiàn)二叉堆以及堆排序的示例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python基于回溯法子集樹(shù)模板實(shí)現(xiàn)8皇后問(wèn)題
這篇文章主要介紹了Python基于回溯法子集樹(shù)模板實(shí)現(xiàn)8皇后問(wèn)題,簡(jiǎn)單說(shuō)明了8皇后問(wèn)題的原理并結(jié)合實(shí)例形式分析了Python回溯法子集樹(shù)模板解決8皇后問(wèn)題的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-09-09Python requests及aiohttp速度對(duì)比代碼實(shí)例
這篇文章主要介紹了Python requests及aiohttp速度對(duì)比代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07numpy中np.append()函數(shù)用法小結(jié)
在numpy的函數(shù)庫(kù)中,np.append()函數(shù)是一個(gè)常用的數(shù)組操作函數(shù),它在進(jìn)行數(shù)組操作時(shí)能夠?qū)蓚€(gè)數(shù)組進(jìn)行拼接,并返回一個(gè)拼接后的新數(shù)組,下面就來(lái)介紹一下具體用法,感興趣的可以了解一下2023-11-11Python 中對(duì) XML 文件的編碼轉(zhuǎn)換問(wèn)題
這篇文章主要介紹了Python 中對(duì) XML 文件的編碼轉(zhuǎn)換問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03Python中注釋(多行注釋和單行注釋)的用法實(shí)例
這篇文章主要給大家介紹了關(guān)于Python中注釋(多行注釋和單行注釋)用法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08python數(shù)字圖像處理之圖像簡(jiǎn)單濾波實(shí)現(xiàn)
這篇文章主要為大家介紹了python數(shù)字圖像處理之圖像簡(jiǎn)單濾波實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06django restframework使用redis實(shí)現(xiàn)token認(rèn)證
本文主要介紹了django restframework使用redis實(shí)現(xiàn)token認(rèn)證,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09python解析中國(guó)天氣網(wǎng)的天氣數(shù)據(jù)
最近學(xué)習(xí)python 感覺(jué)這門腳本語(yǔ)言十分靈活 而且功能十分強(qiáng)大 尤其是他re庫(kù)用于正則匹配十分強(qiáng)大,寫了個(gè)例子解析中國(guó)天氣網(wǎng)2014-03-03