(二叉)堆是一个数组,包括两个属性,A.length(通常)给出数组元素的个数,A.heap_size表示有多少个堆元素存储在该数组中。
1.对于一给定的下标i,我们可以得到它的父节点,左右子节点
def parent(i):
return int(i/2)
def left(i):
return 2*i
def right(i):
return 2*i+1
2.维护堆的性质
对堆排序,使堆满足a[parent(i)]>=a[i]
def max_heapify(self, i): # 维护最大堆性质
l = heap.left(i)
r = heap.right(i)
if l <= self._heap_size and self._a[l] > self._a[i]:
max = l
else:
max = i
if r <= self._heap_size and self._a[r] > self._a[max]:
max = r
if max != i:
self._a[i] ^= self._a[max]
self._a[max] ^= self._a[i]
self._a[i] ^= self._a[max]
heap.max_heapify(self,max)
3.建立最大堆
把每个节点看成根节点,自底向上利用过程max-heapify得到一个最大堆
def build_max_heap(self):
for i in range(int(self._heap_size/2), -1, -1):
heap.max_heapify(self, i)
4.堆排序算法
先利用过程build_max_heap将数组建成最大堆。因为数组最大元素总在根节点a[0]中,通过把它与a[n]进行互换,再从堆中去除节点n(通过减少a.heap_size的值实现),接着借助过程max_heapify维护最大堆的性质,堆排序算法不断重复这一过程,直到堆的大小降到2。
def heap_sort(self):
a_heap_size = self._heap_size
heap.build_max_heap(self)
for i in range(self._heap_size, 0, -1):
self._a[i] ^= self._a[0]
self._a[0] ^= self._a[i]
self._a[i] ^= self._a[0]
self._heap_size -= 1
heap.max_heapify(self,0)
总体代码如下:
class heap(object):
def __init__(self, a):
self._a = a
self._heap_size = len(a)-1
def parent(i):
return int(i/2)
def left(i):
return 2*i
def right(i):
return 2*i+1
def max_heapify(self, i): # 维护最大堆性质
l = heap.left(i)
r = heap.right(i)
if l <= self._heap_size and self._a[l] > self._a[i]:
max = l
else:
max = i
if r <= self._heap_size and self._a[r] > self._a[max]:
max = r
if max != i:
self._a[i] ^= self._a[max]
self._a[max] ^= self._a[i]
self._a[i] ^= self._a[max]
heap.max_heapify(self,max)
def build_max_heap(self):
for i in range(int(self._heap_size/2), -1, -1):
heap.max_heapify(self, i)
def heap_sort(self):
a_heap_size = self._heap_size
heap.build_max_heap(self)
for i in range(self._heap_size, 0, -1):
self._a[i] ^= self._a[0]
self._a[0] ^= self._a[i]
self._a[i] ^= self._a[0]
self._heap_size -= 1
heap.max_heapify(self,0)
self._heap_size = a_heap_size
return self._a