数据结构:堆排序 (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)