本文实例讲述了Python排序搜索基本算法之堆排序。分享给大家供大家参考,具体如下:
堆是一种完全二叉树,堆排序是一种树形选择排序,利用了大顶堆堆顶元素最大的特点,不断取出最大元素,并调整使剩下的元素还是大顶堆,依次取出最大元素就是排好序的列表。举例如下,把序列[26,5,77,1,61,11,59,15,48,19]排序,如下:
基于堆的优先队列算法代码如下:
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
|
def fixUp(a): #在堆尾加入新元素,fixUp恢复堆的条件 k = len (a) - 1 while k> 1 and a[k / / 2 ]<a[k]: a[k / / 2 ],a[k] = a[k],a[k / / 2 ] k = k / / 2 def fixDown(a): #取a[1]返回的值,然后把a[N]移到a[1],fixDown来恢复堆的条件 k = 1 N = len (a) - 1 while 2 * k< = N: j = 2 * k if j<N and a[j]<a[j + 1 ]: j + = 1 if a[k]<a[j]: a[k],a[j] = a[j],a[k] k = j else : break def insert(a,elem): a.append(elem) fixUp(a) def delMax(a): maxElem = a[ 1 ] N = len (a) if N< = 1 : print ( 'There\'s none element in the list' ) return - 1 if N = = 2 : return a[ 1 ] else : a[ 1 ] = a.pop() fixDown(a) return maxElem data = [ - 1 ,] #第一个元素不用,占位 insert(data, 26 ) insert(data, 5 ) insert(data, 77 ) insert(data, 1 ) insert(data, 61 ) insert(data, 11 ) insert(data, 59 ) insert(data, 15 ) insert(data, 48 ) insert(data, 19 ) result = [] N = len (data) - 1 for i in range (N): print (data) result.append(delMax(data)) print (result) |
fixUp函数用于向列表的尾部添加一个新的元素,然后调整成大顶堆;fixDown函数用于取出大顶堆最大的元素后,把列表尾部的元素放到堆顶位置,然后再调整成大顶堆;insert函数是每次插入一个新的元素并调整成为大顶堆;delMax函数把最大的元素返回出来并把剩下的元素调整成为大顶堆。
输出如下:
1
2
3
4
5
6
7
8
9
10
11
|
[ - 1 , 77 , 61 , 59 , 48 , 19 , 11 , 26 , 1 , 15 , 5 ] [ - 1 , 61 , 48 , 59 , 15 , 19 , 11 , 26 , 1 , 5 ] [ - 1 , 59 , 48 , 26 , 15 , 19 , 11 , 5 , 1 ] [ - 1 , 48 , 19 , 26 , 15 , 1 , 11 , 5 ] [ - 1 , 26 , 19 , 11 , 15 , 1 , 5 ] [ - 1 , 19 , 15 , 11 , 5 , 1 ] [ - 1 , 15 , 5 , 11 , 1 ] [ - 1 , 11 , 5 , 1 ] [ - 1 , 5 , 1 ] [ - 1 , 1 ] [ 77 , 61 , 59 , 48 , 26 , 19 , 15 , 11 , 5 , 1 ] |
前面的输出是不断取出最大元素后的大顶堆,由于是完全二叉树,根据列表可以自己写出大顶堆的树形结构,就不在这里赘述,最后一行是排好序的列表。
下面是堆排序算法,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
def fixDown(a,k,n): #自顶向下堆化,从k开始堆化 N = n - 1 while 2 * k< = N: j = 2 * k if j<N and a[j]<a[j + 1 ]: #选出左右孩子节点中更大的那个 j + = 1 if a[k]<a[j]: a[k],a[j] = a[j],a[k] k = j else : break def heapSort(l): n = len (l) - 1 for i in range (n / / 2 , 0 , - 1 ): fixDown(l,i, len (l)) while n> 1 : l[ 1 ],l[n] = l[n],l[ 1 ] fixDown(l, 1 ,n) n - = 1 return l[ 1 :] l = [ - 1 , 26 , 5 , 77 , 1 , 61 , 11 , 59 , 15 , 48 , 19 ] #第一个元素不用,占位 res = heapSort(l) print (res) |
输出如下:
1
|
[ 1 , 5 , 11 , 15 , 19 , 26 , 48 , 59 , 61 , 77 ] |
希望本文所述对大家Python程序设计有所帮助。
原文链接:http://blog.csdn.net/littlethunder/article/details/23877545