2013-04-21 翻閱《算法導論》
再談堆排序
堆排序利用的特性——堆的數據結構特徵:最大/最小 的元素總是在根處取得。
那麼要利用根來排序,我們只需要保持堆的特性,然後每次把最後的元素與根交換,取出根元素就可以了。但是這個過程需要用到整堆,即保證這個數組能夠形成堆的特徵(這裏對最大堆來講):父節點總是比子節點要大。
整堆就是對這種“僭越”的清洗,說起來很殘忍,其實就是如果比自己小的佔用了上位,則和它交換,這樣遞歸下去,就一定能夠讓整棵樹變得“井井有條”。
這次我用python來實現一個堆。
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#!/usr/bin/python # -*- coding: utf-8 -*- ''' # heapsort of python # by bibodeng # 2013-04-21 ''' DEBUG = 1 class heap_sort: array = [] #the array to be sort heap_size = 0 def __init__( self , array): self .array = array #the array to be sort self .heap_size = len ( self .array) - 1 '''print self.array print self.heap_size''' # find the parent node index in array def parent( self ,i): return i>> 1 def left_child( self ,i): return (i<< 1 ) + 1 def right_child( self ,i): return (i<< 1 ) + 2 def heap_max( self ): return self .array[ 0 ] def swap( self ,x,y): return y,x # make the array fit heap from node i def max_heapify( self , i): # judge the i is smaller than his child l = self .left_child(i) r = self .right_child(i) largest = i # left if l < = self .heap_size and array[i] < array[l]: largest = l # right if r < = self .heap_size and array[largest] < array[r] : largest = r # exchange the largest with i if largest ! = i: array[i],array[largest] = self .swap(array[i], array[largest]) # recur self .max_heapify(largest) # make the array is a heap def build_heap( self ): # self.heap_size = self.array.len() for i in range (( self .heap_size / 2 ), - 1 , - 1 ): # print "heapify node", i ,":", self.array[i] self .max_heapify(i) def h_sort( self ): print "before build: " , self .array # first , build heap self .build_heap() # second get the heap node by order # print self.heap_size print "after build: " , self .array for i in range ( self .heap_size, - 1 , - 1 ): # get root print "the " ,i, "num : " , self .heap_max() self .array[ 0 ] = self .array[i] del self .array[i] self .heap_size - = 1 # heapify the array self .max_heapify( 0 ) # call the program to run array = [] if DEBUG = = 1 : array.extend([ 3 , 2 , 5 , 4 , 6 , 9 , 1 , 10 , 20 ]) else : tmp = int ( raw_input ( "input one number :" )) while (tmp > 0 ): array.append(tmp); tmp = int ( raw_input ( "input one number :" )) # 正式驗證程序功能 sort_example = heap_sort(array) sort_example.h_sort() |
優先隊列
在堆的基礎上,添加了增長key功能,這樣增長後的元素要遵守堆的規則,在合適的地方排隊。故而需要自底向上地整堆,如果比父節點大,就一直交換。其實堆本身就已經具備了優先隊列的功能了,增加功能會變得更加靈活,因爲優先權可能是會改變的。
添加一個插入功能,其實是在最後添加一個無窮小的元素(這樣就可以理所當然地排在最後),然後對它進行增長key,然後它的位置就改變了。
by bibodeng 2013-04-21 21:54:21