Skip to content

Commit dc66467

Browse files
committed
heap data structure
1 parent e6ba5ed commit dc66467

5 files changed

Lines changed: 156 additions & 0 deletions

File tree

ch01_basic/at003_insertsort.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"""
55
Topic: sample
66
Desc : 插入排序
7+
由于其内层循环非常紧凑,对于小规模的输入,
8+
插入排序是一种非常快的原址排序算法
9+
注: 如果输入数组中仅有常数个元素需要在排序过程中存储在数组外,
10+
则称这种排序算法是原址的。
711
"""
812
__author__ = 'Xiong Neng'
913

ch01_basic/at012_codefunny.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
# at012: 编程之美的几个小算法
4+
"""
5+
Topic: sample
6+
Desc : 编程之美的几个小算法
7+
"""
8+
__author__ = 'Xiong Neng'
9+
10+
11+
def listChess():
12+
"""
13+
打印连个将/帅的所有合法的位置,
14+
用1..9标明第一个将9个位置,1..9标明第二个帅
15+
"""
16+
for i in range(1, 10):
17+
print([(i, k) for k in range(1, 10) if abs(k - i) % 3 != 0])
18+
19+
if __name__ == '__main__':
20+
listChess()

ch01_basic/at013_randpermute.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
# at013_randpermute: 随机排列数组算法
4+
"""
5+
Topic: sample
6+
Desc : 随机排列数组算法
7+
第一种算法:
8+
对给定的数组A,我们对每个A[i]生成一个随机的优先级
9+
然后根据这个优先级对A进行排序,这个排序需要O(nlg(n))复杂度
10+
第二种算法:
11+
原址排列给定数组,在O(n)时间内完成,在进行第i次迭代时,
12+
A[i]从A[i]至A[n]中随机选取。之后A[i]就再也不变了。
13+
"""
14+
from random import randint, shuffle
15+
16+
__author__ = 'Xiong Neng'
17+
18+
19+
def randPermuteBySort(seq):
20+
"""
21+
对给定的数组A,我们对每个A[i]生成一个随机的优先级
22+
然后根据这个优先级对A进行排序,这个排序需要O(nlg(n))复杂度
23+
"""
24+
maxR = pow(len(seq), 3)
25+
p = []
26+
for i in range(0, len(seq)):
27+
p.append(randint(1, maxR))
28+
seq[:] = [m for (m, n) in sorted(zip(seq, p), key=lambda k: k[1])]
29+
30+
31+
def randPermuteBySwap(seq):
32+
"""
33+
原址排列给定数组,在O(n)时间内完成,在进行第i次迭代时,
34+
A[i]从A[i]至A[n]中随机选取。之后A[i]就再也不变了。
35+
"""
36+
le = len(seq)
37+
for i in range(0, le):
38+
swapIndex = randint(i, le - 1)
39+
seq[i], seq[swapIndex] = seq[swapIndex], seq[i]
40+
41+
42+
if __name__ == '__main__':
43+
se = [4, 5, 12, 44, 56, 6]
44+
randPermuteBySort(se)
45+
print(se)
46+
se = [4, 5, 12, 44, 56, 6]
47+
randPermuteBySwap(se)
48+
print(se)
49+
se = [4, 5, 12, 44, 56, 6]
50+
shuffle(se) # python中的函数
51+
print(se)
52+

ch02_sort/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
"""
4+
Topic: sample
5+
Desc : 排序和顺序统计量
6+
"""
7+
__author__ = 'Xiong Neng'

ch02_sort/at014_heapsort.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
# at014_heapsort: 堆排序
4+
"""
5+
Topic: sample
6+
Desc : 堆排序
7+
堆排序的时间复杂度是O(nlg(n)),并且具有空间原址性
8+
二叉堆heap是一种数据结构,可用来实现优先队列
9+
给定一个节点的下标i(下标从0开始),则其父节点、坐孩子、右孩子坐标:
10+
parent(i) = floor((i+1)/2 - 1) = ((i + 1) >> 1) - 1
11+
left(i) = 2*i + 1 = (i << 1) + 1
12+
right(i) = 2*i + 2 = (i + 1) << 1
13+
14+
最小堆定义: 所有i必须满足A[parent(i)] <= A[i]
15+
最大堆定义: 所有i必须满足A[parent(i)] >= A[i]
16+
17+
在堆排序中,我们使用最大堆
18+
在优先队列算法中,使用最小堆
19+
"""
20+
__author__ = 'Xiong Neng'
21+
22+
23+
def heapSort(heap):
24+
"""
25+
堆排序算法
26+
"""
27+
__buildMaxHeap(heap)
28+
for i in range(heap[2] - 1, 0, -1):
29+
heap[0][0], heap[0][i] = heap[0][i], heap[0][0]
30+
heap[1] -= 1
31+
__maxHeapify(heap, 0)
32+
33+
34+
def __maxHeapify(heap, i):
35+
"""
36+
前提是i的两棵子树left(i)和right(i)的二叉树都是最大堆了
37+
现在加入i节点后,要保持这个二叉树为最大堆的性质
38+
heap: 一个包含[seq,heapSize,length]的数组
39+
"""
40+
seq = heap[0]
41+
slen = heap[1]
42+
while True:
43+
left = (i << 1) + 1
44+
right = (i + 1) << 1
45+
if left < slen and seq[left] > seq[i]:
46+
largest = left
47+
else:
48+
largest = i
49+
if right < slen and seq[right] > seq[largest]:
50+
largest = right
51+
if largest != i:
52+
seq[largest], seq[i] = seq[i], seq[largest]
53+
i = largest
54+
else:
55+
break
56+
57+
58+
def __buildMaxHeap(heap):
59+
"""
60+
由完全二叉树的性质可知:对于 n/2..n-1为下标的元素,都是叶子节点,
61+
那么可从下标floor((i+1)/2 - 1)开始往前到0的元素调用maxHeapify
62+
heap: 一个包含[seq,heapSize,length]的数组
63+
"""
64+
slen = heap[1] = heap[2]
65+
for i in range(((slen + 1) >> 1) - 1, -1, -1):
66+
__maxHeapify(heap, i)
67+
68+
69+
if __name__ == '__main__':
70+
h = [[9, 7, 8, 10, 16, 3, 14, 2, 1, 4], 0, 10]
71+
heapSort(h)
72+
print(h[0])
73+

0 commit comments

Comments
 (0)