最小堆从结构上讲是一棵完全树,所谓k阶最小堆,指的是树的阶数为k。最小堆,指的是树中父结点的值均不大于其叶子节点,在使用堆排序时我们进行n(n为结点个数)次就可得到一个有序序列。以下实现了一个k阶最小堆(当k为1时,构建完毕后就已经是有序序列)。
#!/usr/bin/python
# -*- coding: utf-8 -*-
#ecoding=utf-8
class KHeap:
def __init__(self, lst=[], k=int(2)):
"""
uses a Python list to store a heap and an integer to store an order
:param lst: a list to store the heap
:param k: an integer to store an order,order means the number of nodes with the largest number of children nodes
:return: None
"""
self.list = lst
self.size = int(len(lst))
self.order = int(k)
self.build(self.list)
# self.list.sort()
# i = len(src_list) / 2
# # self.size = len(src_list)
# # self.list.extend(src_list)
# while i > 0 :
# self.down(i)
# i -= 1
pass
def up(self, i) :
"""
if the child node is smaller than the parent node, the location of the parent and child nodes is exchanged
:param i: the index of child node
:return:
"""
i = i - 1
while (i - 1)//self.order >= 0 :
if self.list[(i - 1)//self.order] > self.list[i]:
self.list[(i - 1)//self.order] , self.list[i] = self.list[i],self.list[(i - 1)//self.order]
i = (i - 1)//self.order
pass
def down(self, i) :
"""
initialize the time from the beginning of the first node to add
:param i: the value of node
:return:
"""
for i_add in range(1,self.order+1):
if (i*self.order+i_add) <= self.size - 1:
if self.list[int(i)] > self.list[int(i*self.order+i_add)]:
# print 'exchange:',self.list[i],self.list[i*self.order+i_add]
self.list[int(i)],self.list[int(i*self.order+i_add)] = self.list[int(i*self.order+i_add)],self.list[int(i)]
pass
def insert(self, v='unkonwn'):
"""
inserts a new node with value v
:param v: the value to insert
:return:
"""
# print ('insert_list:'),(self.list)
# print ('value_insert:'),(v)
# print type(v)
# if type(v) == str:
# return None
# else:
self.list.append(v)
self.size = self.size + 1
# self.list.sort()
# temp_list = self.list
# temp_list.sort()
# self.list = temp_list
# the default is inserted into the tail node
# if the child node is smaller than the parent node, then the up operation is performed
self.up(self.size)
pass
def build(self, src_list) :
"""
Build a heap
:param src_list:
:return:
"""
self.size = len(src_list)
self.list = src_list
#The last index of a non-leaf node
j = (len(self.list) - 1 - 1) // self.order
while j >= 0:
i = (len(self.list) - 1 - 1) // self.order
while i >= 0 :
self.down(i)
# i = (i - 1)/self.order
i = i - 1
j = (j-1)//self.order
def remove_min(self):
if len(self.list) == 0:
return None
else:
# temp_list = self.list
# temp_list.sort()
#
# self.list = temp_list[1:]
#print (self.list[:20])
a = self.list[0]
self.list = self.list[1:]
self.size = self.size - 1
self.list[0],self.list[self.size-1] = self.list[self.size-1],self.list[0]
print self.list
i = 0
while i*self.order <= self.size-1:
for i_add in range(1,self.order+1):
if self.list[int(i)] > self.list[int(i*self.order+i_add)]:
print self.list[i]
self.list[int(i)],self.list[int(i*self.order+i_add)] = self.list[int(i*self.order+i_add)],self.list[int(i)]
i = i*self.order+i_add
else:
return a
return a
def check_condition(self, someKey):
"""
Detects whether all nodes and their child nodes meet the conditions
:param someKey:someKey condition
:return:
"""
flag = True
i = (len(self.list) - 1 - 1) // self.order
flag = True
while i >= 0:
for i_add in range(1,self.order+1):
if (i*self.order+i_add) <= self.size - 1:
value_parent = someKey(self.list[int(i)])
value_child = self.list[int(i*self.order+i_add)]
if value_parent > value_child:
flag = False
i = i -1
return flag
def __str__(self):
"""
computes the string representation of the KHeap object
:return: tree structure of the heap
"""
return str(self.list)
pass
def someKey(n):
if n % 2 == 1:
return 3*n
else:
return 8*n
mh = KHeap([20,15,9,10,25,26,90,40,200,19,100,70,170,12,27])
print mh
print mh.remove_min()
print mh.remove_min()
print mh.remove_min()
print mh.remove_min()
#
# print mh.remove_min(),mh
# print mh.remove_min(),mh
# print mh.remove_min(),mh
# print mh.remove_min(),mh
# print mh.remove_min(),mh
# for i in range(100000):
# print mh.insert(i)
# print mh
# mh.insert(5)
# mh.insert(4)
# mh.insert(5)
# print mh.remove_min()
# print mh