用python的堆及堆排序:
堆调整的两个方面(以最小堆说明):
1. 删除堆顶元素:(自顶向下)
删除堆顶元素时,把最后一个节点 last_indx 移到堆顶, 将此节点称作cur。
当此cur元素的两个子节点元素中最小者大于其,则将其子节点最小者k与cur交换,并将k作为新的cur。再将cur与其两个子节点进行比较。直到cur两个子节点都比cur小 或者 cur 为叶子节点时为止。
2. 添加元素:(自底向上)
添加节点时,将此节点置于完全二叉树的最后一个节点,将此节点称作cur。
当此节点小于其父节点K时,将cur与K交互,并将k作为新的cur。再继续将cur与其父节点进行比较。直到cur结点比其父节点大或者cur为根节点。
python 实现:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# python
class HeapNode:
w = None
v = None
next_indx = -1
up_benefit = 0
def __init__( self, w, v, next_indx, up_benefit ):
self.w = w
self.v = v
self.next_indx = next_indx
self.up_benefit = up_benefit
def compare( node_1, node_2 ):
# print( node_1.up_benefit, node_2.up_benefit )
return node_1.up_benefit < node_2.up_benefit
# python 实现的 Heap
class Heap:
# compare = None
last_indx = -1
heap = []
def __init__( self, compare = compare ):
self.compare = compare
self.last_indx = -1
def parent( self, i ):
if i <= 0:
return -1
return int( (i-1)/2.0 )
def lchild( self, i):
tmp = 2*i + 1
if tmp > self.last_indx:
return -1
return tmp
def rchild( self, i):
tmp = 2*i + 2
if tmp > self.last_indx:
return -1
return tmp
def up_fix( self, i ):
parent = self.parent( i )
if -1 == parent:
return
print( "[up_fix] before adjust :")
self.disp()
if self.compare( self.heap[parent], self.heap[i] ):
return
#交换heap[i],heap[parent]
tmp = self.heap[parent]
self.heap[parent] = self.heap[i]
self.heap[i] = tmp
self.up_fix( parent )
print( "[up_fix] after adjust :")
self.disp()
def down_fix( self, i ):
l_child = self.lchild( i )
r_child = self.rchild( i )
best_id = i
if l_child != -1 and not self.compare( self.heap[i], self.heap[l_child] ):
best_id = l_child
if r_child != -1 and not self.compare( self.heap[i], self.heap[r_child] ):
best_id = r_child
if best_id == i:
return
tmp = self.heap[i]
self.heap[i] = self.heap[best_id]
self.heap[best_id] = tmp
self.down_fix( best_id )
def insert( self, node ):
if len(self.heap)==0:
self.heap = []
self.last_indx = -1
self.last_indx += 1
self.heap.append( node )
self.up_fix( self.last_indx )
def delete( self ):
if len(self.heap) < 1:
return None
tmp = self.heap[0]
self.last_indx -= 1
self.heap.insert( 0, self.heap[ len(self.heap)-1 ] )
del self.heap[1]
del self.heap[ len(self.heap)-1 ]
if self.last_indx < 0:
return tmp
self.down_fix( 0 )
return tmp
def top( self ):
if self.last_indx > -1:
return self.heap[0]
return None
def disp( self ):
tmp = []
for i in self.heap:
tmp.append( i.up_benefit )
print( "[heap] " )
print( tmp )
def test_Heap():
l = [1, -1, -2, 3, 0 ]
my_heap = Heap()
for i in l:
my_heap.insert( HeapNode(0,0,0,i) )
# my_heap.disp()
ret = []
while True:
tmp = my_heap.delete()
if tmp == None:
break
ret.append( tmp.up_benefit )
print( "\n\n堆排序输出:" )
print( ret )
if __name__ == '__main__':
test_Heap()
运行结果:
最后一行为排序之后的输出。