Python堆排序之heapq
堆排序 (๑• . •๑)
這是崔斯特的第七十八篇原創文章
Python中的堆排序
heapq模組實現了Python中的堆排序,並提供了有關方法。讓用Python實現排序演算法有了簡單快捷的方式。
heapq的官方文件和原始碼: ofollow,noindex">Heap queue algorithm
下面通過舉例的方式說明heapq的應用方法
實現堆排序
from heapq import * def heap_sort(iterable): h = [] for value in iterable: heappush(h, value) return [heappop(h) for _ in range(len(h))] if __name__ == '__main__': print(heap_sort([1, 3, 5, 9, 2, 123, 4, 88]))
Output: [1, 2, 3, 4, 5, 9, 88, 123]
下面說說幾個主要方法
heappush()
heapq.heappush(heap, item):將item壓入到堆陣列heap中。如果不進行此步操作,後面的heappop()失效
heappop()
heapq.heappop(heap):從堆陣列heap中取出最小的值,並返回。
>>>h = []#定義一個list >>>from heapq import *#引入heapq模組 >>>h [] >>>heappush(h, 5)#向堆中依次增加數值 >>>heappush(h, 2) >>>heappush(h, 3) >>>heappush(h, 9) >>>h#h的值 [2, 5, 3, 9] >>>heappop(h)#從h中刪除最小的,並返回該值 2 >>>h [3, 5, 9] >>>h.append(1)#注意,如果不是壓入堆中,而是通過append追加一個數值 >>>h#堆的函式並不能操作這個增加的數值,或者說它堆對來講是不存在的 [3, 5, 9, 1] >>>heappop(h)#從h中能夠找到的最小值是3,而不是1 3 >>>heappush(h, 2)#這時,不僅將2壓入到堆內,而且1也進入了堆。 >>>h [1, 2, 9, 5] >>>heappop(h)#操作物件已經包含了1 1
heapq.heappushpop(heap, item)
是上述heappush和heappop的合體,同時完成兩者的功能.注意:相當於先操作了heappush(heap,item),然後操作heappop(heap)
>>>h [1, 2, 9, 5] >>>heappop(h) 1 >>>heappushpop(h, 4)#增加4同時刪除最小值2並返回該最小值,與下列操作等同: 2#heappush(h,4),heappop(h) >>>h [4, 5, 9]
heapq.heapify(x)
x必須是list,此函式將list變成堆,實時操作。從而能夠在任何情況下使用堆的函式。
>>>a = [3, 6, 1] >>>heapify(a)#將a變成堆之後,可以對其操作 >>>heappop(a) 1 >>>b = [4, 2, 5]#b不是堆,如果對其進行操作,顯示結果如下 >>>heappop(b)#按照順序,刪除第一個數值並返回,不會從中挑選出最小的 4 >>>heapify(b)#變成堆之後,再操作 >>>heappop(b) 2
heapq.heapreplace(heap, item)
是heappop(heap)和heappush(heap,item)的聯合操作。注意,與heappushpop(heap,item)的區別在於,順序不同,這裡是先進行刪除,後壓入堆
>>>a = [] >>>heapreplace(a, 3)#如果list空,則報錯 Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: index out of range >>>heappush(a, 3) >>>a [3] >>>heapreplace(a, 2)#先執行刪除(heappop(a)->3),再執行加入(heappush(a, 2)) 3 >>>a [2] >>>heappush(a, 5) >>>heappush(a, 9) >>>heappush(a, 4) >>>a [2, 4, 9, 5] >>>heapreplace(a, 6)#先從堆a中找出最小值並返回,然後加入6 2 >>>a [4, 5, 9, 6] >>>heapreplace(a, 1)#1是後來加入的,在1加入之前,a中的最小值是4 4 >>>a [1, 5, 9, 6]
heapq.merge(*iterables)
舉例:
>>> a = [2, 4, 6] >>> b = [1, 3, 5] >>> c = merge(a, b) >>> list(c) [1, 2, 3, 4, 5, 6]
在 歸併排序 中詳細演示了本函式的使用方法。
heapq.nlargest(n, iterable[, key]),heapq.nsmallest(n, iterable[, key])
獲取列表中最大、最小的幾個值。
>>> a [2, 4, 6] >>> nlargest(2,a) [6, 4]
陣列中的第K個最大元素
其實以上說了那麼多,只是為了說這道題。
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。
示例 1:
輸入: [3,2,1,5,6,4] 和 k = 2 輸出: 5
示例 2:
輸入: [3,2,3,1,2,4,5,5,6] 和 k = 4 輸出: 4
說明:
你可以假設 k 總是有效的,且 1 ≤ k ≤ 陣列的長度。
這裡不說別的解法。當然面試中你肯定不能這麼寫,但這是一個很好的思路
class Solution: def findKthLargest(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ import heapq heapq.heapify(nums) return heapq.nlargest(k, nums)[-1]
看到有人用 return sorted(nums)[-k]
,真的要被氣死了。