数据结构:堆排序 (python版) 小顶堆实现从大到小排序 | 大顶堆实现从小到大排序

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 '''
 5 Author: Minion-Xu
 6 
 7 小堆序实现从大到小排序,大堆序实现从小到大排序
 8 重点的地方:小堆序堆顶的元素一定是堆里最小的,大堆序堆顶的元素一定是堆里最大的
 9 小堆序:满足任何从上到下的线路依次增长
10 大堆序:满足任何从上到下的线路依次减小
11 
12 效率:时间效率O(nlogn)
13      空间效率O(1)
14 '''
15 
16 
17 #堆排序:因为队列里的元素是不满足小堆序的,所以首先要构建小堆序
18 #构建完小堆序后,从堆顶弹出元素(该元素最小)并将其放在堆的末尾;以此循环执行
19 #最终形成从大到小排序的队列
20 def little_heap_sort(elems):
21     def siftdown(elems, e, begin, end):
22         i, j = begin, begin*2+1
23         while j < end:
24             if j+1 < end and elems[j] > elems[j+1]:
25                 j += 1
26             if e < elems[j]:
27                 break
28             elems[i] = elems[j]
29             i, j = j, j*2 + 1
30         elems[i] = e
31 
32     #构建小堆序   O(n)
33     end = len(elems)
34     for i in range(end//2, -1, -1):
35         siftdown(elems, elems[i], i, end)
36 
37     #弹出堆顶元素放在末尾  O(nlogn)
38     for i in range(end-1, 0, -1):       #O(n)
39         e = elems[i]
40         elems[i] = elems[0]
41         siftdown(elems, e, 0, i)        #O(logn)
42 
43 
44 
45 # 堆排序:因为队列里的元素是不满足大堆序的,所以首先要构建大堆序
46 # 构建完大堆序后,从堆顶弹出元素(该元素最大)并将其放在堆的末尾;以此循环执行
47 # 最终形成从大到小排序的队列
48 def big_head_sort(elems):
49     def siftdown(elems, e, begin, end):
50         i, j = begin, begin*2 + 1
51         while j < end:
52             if j+1 < end and elems[j]<elems[j+1]:
53                 j += 1
54             if e > elems[j]:
55                 break
56             elems[i] = elems[j]
57             i, j = j, j*2 + 1
58         elems[i] = e
59 
60     #构建大堆序 O(n)
61     end = len(elems)
62     for i in range(end//2, -1, -1):
63         siftdown(elems, elems[i], i, end)
64 
65     #弹出堆顶元素放在末尾 O(nlogn)
66     for i in range(end-1, 0, -1):
67         e = elems[i]
68         elems[i] = elems[0]
69         siftdown(elems, e, 0, i)
70 
71 if __name__=="__main__":
72     l = [1,6,2,9,8,0,3,5,4,7]
73     little_heap_sort(l)
74     print(l)
75     #[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
76     big_head_sort(l)
77     print(l)
78     #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

堆排序:          构建堆序, 堆顶弹出, 放在堆尾,

    (原)堆尾元素, 充当堆顶,向下筛选(siftdown)

原文地址:https://www.cnblogs.com/xautxuqiang/p/6126639.html