算法导论 排序算法

堆排序

二叉堆是一个数组,可以被看作一个近似的完全二叉树。二叉堆可以分为两种形式:最大堆和最小堆。
在最大堆中,最大堆性质是指除了根以外的所有结点i都满足:$A[PARENT[i]]>=A[i]$
也就是说,某节点的值之多与其父结点一样大,因此,堆中的最大元素存放在根结点,并且,在任意子树中,该子树所包含的所有结点的数值都不大于该子树根结点的值。

最小堆性质是指除了根以外的所有结点i都满足:$A[PARENT[i]]<=A[i]$
堆中最小元素存放在根结点中。

堆的高度是$lg n$,n是结点数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"""维护堆的性质:
输入一个数组A和下标i,调用MaxHeapify时,假定根结点为左子树LEFT(i)和右子树RIGHT(i)的二叉树都是最大堆,
但此时A[i]可能会小于其孩子,这就违背了最大堆的性质。
调用MaxHeapify通过让A[i]的值在最大堆中“逐级下降”,从而使得以下标i为根结点的子树重新遵循最大堆的性质。
时间复杂度:$T(n) leq T(2n/3)+O(1),T(n)=O(lg n),h=lg n$
"""
def (A, i, size):
left=i<<1
right=(i<<1)+1
largest=i

if left<size and A[left]>A[i]:
largest=left
if right<size and A[right]>A[largest]:
大专栏  算法导论 排序算法 largest=right
if largest!=i:
A[i],A[largest]=A[largest],A[i]
MaxHeapify(A, largest, size)

"""建堆:
自底向上的方法利用MaxHeapify,把一个大小为n=A.length的数组A[1...n]转换为最大堆。
子数组A[lfloor n/2 rfloor+1...n]中的元素都是树的叶结点。每个叶结点都看作只有一个元素的最大堆。
时间复杂度:O(n),线性时间内把无序数组构造成一个最大堆
"""
def (A, size):
for i in range(0,len(A)//2)[::-1]:
MaxHeapify(A, i, size)
return A

"""堆排序算法:
用BuildMaxHeap将输入数组A[0...n-1]构建成最大堆,其中n=A.length。
因为数组中的最大元素总在根结点A[0]中,通过它与将A[n-1]进行互换,让该元素放到正确的位置。
如果从堆中去掉结点n(A.heapsize-1),剩余结点中,原来根结点的孩子结点仍然时最大堆,而
最新的根结点可能会违背最大堆性质,为维护最大堆性质,要调用MaxHeapify(A,0,size),
从而使在A[0...n-2]上构造一个新的最大堆,直至堆的大小从n-1降到2
时间复杂度:$O(n lg n)$,BuildMaxHeap是O(n),n-1次调用MaxHeapify $ O(lg n)$
"""
def HeapSort(A):
size=len(A)
BuildMaxHeap(A, size)

for i in range(1, len(A))[::-1]:
A[0],A[i]=A[i],A[0]
size-=1
MaxHeapify(A, 0, size)
return A

if __name__=='__main__':
import random
print( "Now displaying HeapSort")
s = random.randint(5, 10)
A = []
for i in range(0, s):
A.append(random.randint(0, 1000))
print (A)
print (HeapSort(A))



猜你喜欢

转载自www.cnblogs.com/liuzhongrong/p/11986087.html
今日推荐