手寫堆排序
阿新 • • 發佈:2022-05-11
參考:https://zhongqiang.blog.csdn.net/article/details/115319669
class S(): def __init__(self) -> None: pass # 堆排序 def heapify(self, tree, n, i): """把父節點和最大子節點交換 :param n: 總共的節點個數 :param i: 元素的索引, 對第i個元素做heapify """ # if i >= n: # 遞迴出口 0 <= i <= (n-1),但是由於並不會越界,此處不需要遞迴出口 # return c1 = 2 * i + 1 # 左邊子節點 c2 = 2 * i + 2 # 右邊子節點 # 找出父節點&兩個子節點中最大的節點 max_ele = i # 假設父節點為最大值 if c1 < n and tree[c1] > tree[max_ele]: max_ele = c1 if c2 < n and tree[c2] > tree[max_ele]: max_ele = c2 if max_ele != i: tree[max_ele], tree[i] = tree[i], tree[max_ele] # 遞迴 如果原先是max_ele節點,這裡會被調換過,就是比較大的值被拿到父節點,換來了一個比較小的數,需要往下遞迴下去 self.heapify(tree, n, max_ele) def build_heap(self, tree, n): """建堆; :param n: 陣列的長度或者節點的個數 """ last_node = n - 1 # 最後一個節點 parent = (last_node - 1) // 2 # 最後一個節點對應的父節點 # 從最後一個非葉子節點逆序遍歷, 調整建堆 for i in range(parent, -1, -1): self.heapify(tree, n, i) def HeapSort(self, tree, n): # tree 陣列,n 長度 """堆排序""" self.build_heap(tree, n) for i in range(n - 1, -1, -1): # 最後一個節點和最頂上的節點交換 tree[0], tree[i] = tree[i], tree[0] # 拿出(砍斷)最後一個節點(上一步交換完後最大的數已經在最後了), # 而後從最頂上節點開始 heapify,又往下遞迴,直到形成穩定堆 # 此處 heapify的引數是 i 而不是 n,因為不斷砍斷以後,整個陣列長度從 n 變成了 i self.heapify(tree, i, 0) return tree s = S() nums = [1, 3, 2, 6, 2, 0, 4, 8, 1] print(s.HeapSort(nums, len(nums))) # [0, 1, 1, 2, 2, 3, 4, 6, 8]