title: ‘排序算法:堆排序’
date: 2019-12-24 15:09:06
categories:
- 算法導論
tags: - 算法導論
堆排序
-
堆排序思路是,首先構建一個堆,然後根和葉子節點進行交換,從而達到目的
-
堆構建算法:
def build_max_heap(heap): # 構造一個堆,將堆中所有數據重新排序 heapSize = len(heap) for i in range((heapSize -2)//2,-1,-1): # 自底向上建堆 max_heapify(heap, heapSize, i)
-
堆排序算法:
def heap_sort(heap): # 將根節點取出與最後一位做對調,對前面len-1個節點繼續進行堆調整過程。 build_max_heap(heap) # 調整後列表的第一個元素就是這個列表中最大的元素,將其與最後一個元素交換,然後將剩餘的列表再遞歸的調整爲最大堆 for i in range(len(heap)-1, -1, -1): heap[0], heap[i] = heap[i], heap[0] max_heapify(heap, i, 0)
小根堆:
-
堆調整算法:
def max_heapify(heap,heapSize,root): # 調整列表中的元素並保證以root爲根的堆是一個大根堆 ''' 給定某個節點的下標root,這個節點的父節點、左子節點、右子節點的下標都可以被計算出來。 父節點:(root-1)//2 左子節點:2*root + 1 右子節點:2*root + 2 即:左子節點 + 1 ''' left = 2*root + 1 right = left + 1 larger = root if left < heapSize and heap[larger] < heap[left]: larger = left if right < heapSize and heap[larger] < heap[right]: larger = right if larger != root: # 如果做了堆調整則larger的值等於左節點或者右節點的值,這個時候做堆調整操作 heap[larger], heap[root] = heap[root], heap[larger] # 遞歸的對子樹做調整 max_heapify(heap, heapSize, larger)#下沉操作
-
總體代碼:
# 小根堆 def max_heapify(heap,heapSize,root): # 調整列表中的元素並保證以root爲根的堆是一個大根堆 ''' 給定某個節點的下標root,這個節點的父節點、左子節點、右子節點的下標都可以被計算出來。 父節點:(root-1)//2 左子節點:2*root + 1 右子節點:2*root + 2 即:左子節點 + 1 ''' left = 2*root + 1 right = left + 1 larger = root if left < heapSize and heap[larger] < heap[left]: larger = left if right < heapSize and heap[larger] < heap[right]: larger = right if larger != root: # 如果做了堆調整則larger的值等於左節點或者右節點的值,這個時候做堆調整操作 heap[larger], heap[root] = heap[root], heap[larger] # 遞歸的對子樹做調整 max_heapify(heap, heapSize, larger)#下沉操作 def build_max_heap(heap): # 構造一個堆,將堆中所有數據重新排序 heapSize = len(heap) for i in range((heapSize -2)//2,-1,-1): # 自底向上建堆 max_heapify(heap, heapSize, i) def heap_sort(heap): # 將根節點取出與最後一位做對調,對前面len-1個節點繼續進行堆調整過程。 build_max_heap(heap) # 調整後列表的第一個元素就是這個列表中最大的元素,將其與最後一個元素交換,然後將剩餘的列表再遞歸的調整爲最大堆 for i in range(len(heap)-1, -1, -1): heap[0], heap[i] = heap[i], heap[0] max_heapify(heap, i, 0) # 測試 if __name__ == '__main__': a = [30, 50, 57, 77, 62, 78, 94, 80, 84] print(a) heap_sort(a) print(a) # b = [random.randint(1,1000) for i in range(1000)] # print(b) # heap_sort(b) # print(b)
大根堆
-
調整算法:
def max_heapify(heap,heapSize,root): # 調整列表中的元素並保證以root爲根的堆是一個大根堆 ''' 給定某個節點的下標root,這個節點的父節點、左子節點、右子節點的下標都可以被計算出來。 父節點:(root-1)//2 左子節點:2*root + 1 右子節點:2*root + 2 即:左子節點 + 1 ''' left = 2*root + 1 right = left + 1 larger = root if left < heapSize and heap[larger] > heap[left]: larger = left if right < heapSize and heap[larger] > heap[right]: larger = right if larger != root: # 如果做了堆調整則larger的值等於左節點或者右節點的值,這個時候做堆調整操作 heap[larger], heap[root] = heap[root], heap[larger] # 遞歸的對子樹做調整 max_heapify(heap, heapSize, larger)
-
總體代碼:
# 大根堆 def max_heapify(heap,heapSize,root): # 調整列表中的元素並保證以root爲根的堆是一個大根堆 ''' 給定某個節點的下標root,這個節點的父節點、左子節點、右子節點的下標都可以被計算出來。 父節點:(root-1)//2 左子節點:2*root + 1 右子節點:2*root + 2 即:左子節點 + 1 ''' left = 2*root + 1 right = left + 1 larger = root if left < heapSize and heap[larger] > heap[left]: larger = left if right < heapSize and heap[larger] > heap[right]: larger = right if larger != root: # 如果做了堆調整則larger的值等於左節點或者右節點的值,這個時候做堆調整操作 heap[larger], heap[root] = heap[root], heap[larger] # 遞歸的對子樹做調整 max_heapify(heap, heapSize, larger) def build_max_heap(heap): # 構造一個堆,將堆中所有數據重新排序 heapSize = len(heap) for i in range((heapSize -2)//2,-1,-1): # 自底向上建堆 max_heapify(heap, heapSize, i) def heap_sort(heap): # 將根節點取出與最後一位做對調,對前面len-1個節點繼續進行堆調整過程。 build_max_heap(heap) # 調整後列表的第一個元素就是這個列表中最大的元素,將其與最後一個元素交換,然後將剩餘的列表再遞歸的調整爲最大堆 for i in range(len(heap)-1, -1, -1): heap[0], heap[i] = heap[i], heap[0] max_heapify(heap, i, 0) # 測試 if __name__ == '__main__': a = [30, 50, 57, 77, 62, 78, 94, 80, 84] print(a) heap_sort(a) print(a) # b = [random.randint(1,1000) for i in range(1000)] # print(b) # heap_sort(b) # print(b)