堆排序的Python實現


堆排序的思想: 堆是一種數據結構,可以將堆看作一棵完全二叉樹,這棵二叉樹滿足,任何一個非葉節點的值都不大於(或不小於)其左右孩子節點的值。 將一個無序序列調整為一個堆,就可以找出這個序列的最大值(或最小值),然后將找出的這個值交換到序列的最后一個,這樣有序序列就元素就增加一個,無序序列元素就減少一個,對新的無序序列重復這樣的操作,就實現了排序。

堆排序的執行過程:

1.從無序序列所確定的完全二叉樹的第一個非葉子節點開始,從右至左,從下至上,對每個節點進行調整,最終將得到一個大頂堆。

    對節點的調整方法:將當前節點(假設為a)的值與其孩子節點進行比較,如果存在大於a的值的孩子節點,則從中選出最大的一個與a交換。當a來到下一層的時候重復上述過程,直到a的孩子節點的值都小於a為止

2.將當前無序序列中的第一個元素(反映在數中是根節點b),與無序序列中的最后一個元素交換(假設為c),b進入有序序列,到達最終位置。無序序列元素減少1個,有序序列元素增加1個,此時只有節點c可能不滿足堆的定義,對其進行調整。

3.重復2 的過程,直到無序序列的元素剩下一個時排序結束。

 1 # -*- coding:utf-8 -*-
 2 # 堆排序適用於記錄數很多的情況
 3 
 4 from collections import deque
 5 
 6 # 這里需要說明元素的存儲必須要從1開始
 7 # 涉及到左右節點的定位,和堆排序開始調整節點的定位
 8 # 在下標0處插入0,它不參與排序
 9 L = deque([49,38,65,97,76,13,27,49])
10 L.appendleft(0)
11 
12 #L = [0,49,38,65,97,76,13,27,49]
13 
14 def element_exchange(numbers,low,high):
15 
16     temp = numbers[low]
17 
18     # j 是low的左孩子節點(cheer!)
19     i = low
20     j = 2*i
21 
22     while j<=high:
23         # 如果右節點較大,則把j指向右節點
24         if j<high and numbers[j]<numbers[j+1]:
25             j = j+1
26         if temp<numbers[j]:
27             # 將numbers[j]調整到雙親節點的位置上
28             numbers[i] = numbers[j]
29             i = j
30             j = 2*i
31         else:
32             break
33     # 被調整節點放入最終位置
34     numbers[i] = temp
35 
36 def top_heap_sort(numbers):
37 
38     length = len(numbers)-1
39 
40     # 指定第一個進行調整的元素的下標
41     # 它即該無序序列完全二叉樹的第一個非葉子節點
42     # 它之前的元素均要進行調整
43     # cheer up!
44     first_exchange_element = length/2
45 
46     #建立初始堆
47     print first_exchange_element
48     for x in range(first_exchange_element):
49         element_exchange(numbers,first_exchange_element-x,length)
50 
51     # 將根節點放到最終位置,剩余無序序列繼續堆排序
52     # length-1 次循環完成堆排序
53     for y in range(length-1):
54         temp = numbers[1]
55         numbers[1] = numbers[length-y]
56         numbers[length-y] = temp
57         element_exchange(numbers,1,length-y-1)
58 
59 if __name__=='__main__':
60     top_heap_sort(L)
61     for x in range(1,len(L)):
62         print L[x],

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM