python 堆排序

# 二叉樹的遍歷# 對二叉樹中的全部元素不重複的訪問一遍# 廣度優先遍歷#   層序遍歷#       從第一層開始,沒一層從左至右遍歷元素# 深度優先遍歷# 假設樹的根節點爲D,左子樹爲L,右子樹爲R,且要求L必定在R以前,則有如下遍歷方式:#   前序遍歷:也叫先序遍歷,也叫先根遍歷,DLR#   中序遍歷:也叫中根遍歷,LDR#   後序遍歷:也叫後根遍歷,LRD# 遍歷序列:將樹中全部元素遍歷一遍後,獲得的元素的序列,將層次結構轉換成了線性結構# 堆排序# 堆是一個徹底二叉樹# 每一個非葉子結點的值都要大於或者等於其左右孩子結點的值,稱爲大頂堆# 每一個非葉子結點的值都要小於或者等於其左右孩子結點的值,稱爲小頂堆# 根結點必定是大頂堆中的最大值,必定是小頂堆中的最小值# 例子:構建一個徹底二叉樹(序列 -> 徹底二叉樹 -> 大頂堆 -> 排序 - > 大頂堆 -> 排序 ...)#   待排序數字爲:30 20 80 40 50 10 60 70 90#   構建一個徹底二叉樹存放數據,並根據性質5對元素編號,放入順序的數據結構中#       性質5:按層依次編號#   構建一個列表爲[0, 30, 20, 80, 40, 50, 10, 60, 70, 90]***#       0爲補位,由於列表下表從0開始,想從1開始進行使用#   構建大頂堆的核心算法#       度數爲2的結點A,若是它的左右孩子結點的最大值比它大,將這個最大值和該結點交換#       度數爲1的結點A,若是它的左孩子的值比它大,則交換#       若是結點A被交換到新的位置,還須要和其孩子結點重複上面的過程#   構建大頂堆 - 起點結點的選擇#       從徹底二叉樹的最後一個結點的雙親結點開始,即最後一層的最右邊葉子結點的父節點開始***#       結點數爲n,則起始結點的編號n//2(性質5)#   構建大頂堆 - 下一個結點的選擇#       從起始結點開始向左找其同層結點,到頭後再從上一層的最右邊結點開始繼續向左逐個查找,直到根節點#       下一結點:n -> n-1 -> n-2 ... 1#   跟結點計算完畢後,若是有交換,則還須要向下對左右子樹進行再次排序# 大頂堆的目標#       確保每一個結點的值都比左右結點的值大# 排序#   將大頂堆根結點這個最大值和最後一個葉子結點交換,那麼最後一個葉子結點就是最大值,將這個葉子結點排除在待排序結點外#   從根結點開始(新的根結點),從新調整爲大頂堆後,重複上一步# 將列表打印成樹(堆排序輔助函數)import mathdef printTree(lst):    treeLen  = len(lst)    treeLay = math.ceil(math.log2(treeLen + 1)) # 樹層數    index = 0    treeWidth = 2 ** treeLay - 1    # 樹寬度    for i in range(treeLay):        for j in range(2**i):            print('{:^{}}'.format(lst[index], treeWidth), end=' ')            index += 1            if index >= treeLen:                break        treeWidth = treeWidth//2        print()lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]printTree(lst)# 調整當前節點def heap_adjust(n, i, array:list):  # array:list 表示array變量的類型是list    '''    調整當前節點核心算放    :param n: 待比較數字的個數    :param i: 當前節點的下標    :param array: 待排序數據    :return:None    '''    while 2 * i <= n:   # 性質5,=n只有左子樹        # 孩子結點判斷2i爲左孩子,2i+1爲右孩子        lChild_index = 2 * i        maxChild_index = lChild_index # n=2i        if n > lChild_index and array[lChild_index + 1] > array[lChild_index]:  # n>2i說明還有右孩子            maxChild_index = lChild_index + 1   # n=2i+1        # 和子樹的根節點比較        if array[maxChild_index] > array[i]:            array[i], array[maxChild_index] = array[maxChild_index], array[i]   # 交換            i = maxChild_index # 被交換後,須要判斷是否還須要調整        else:            break        printTree(array)        print('--------------------------')# 構建大頂堆def maxHeap(total, array:list):    for i in range(total//2, 0, -1):        heap_adjust(total, i, array)    # 調整當前結點    return arraytotal = 9origin = [0,30, 20, 80, 40, 50, 10, 60, 70, 90]print('maxHeap is ')printTree(maxHeap(total, origin))# 結論:第一層是最大值,第二層必定有個次大值
相關文章
相關標籤/搜索