最大ヒープの特性に応じて、
各データに優先順位を付けます。優先順位の高い方が上位層に、小さい方が下位層になります。次に、最初にルート順序をトラバースします。
#实现一个定长的数组arroy
class Array(object):
#初始化
def __init__(self,size = 32):
#
self._size = size
#长度为size,value全为None的列表
self._items = [None] * size
#通过[]获取value
def __getitem__(self,index):
return self.items[index]
#下标赋值
def __setitem__(self,index,value):
self._items[index] = value
#返回长度
def __len__(self):
return self._size
#清除数组
def cleor(self,value = None):
for i in range(len(self.items)):
self._items[i] = value
#遍历数组
def __iter__(self):
for item in self._items:
yield item
################################################################
#实现一个堆排序
################################################################
class MaxHeap(object):
#初始化
def __init__(self,maxsize = None):
#定义一个最大长度
self.maxsize = maxsize
#定义个数
self._count = 0
#新建一个数组
self._elements = Array(maxsize)
#长度
def __len__(self):
#直接返回元素的个数
return self._count
#添加方法
def add(self,value):
#首先判断换是否超出了最大长度
if self.count >= self.maxsize:
raise Exception('full')
#把值赋给节点
self._elements[self._count] = value
#长度加一
self._count += 1
#调用silfup方法
self.silfup(self._count - 1)
#判断位置方法
def _silfup(self, ndx):
#判断换长度
if ndx > 0 :
#计算上一个节点的下标
parent = ((ndx-1) / 2)
#判断子节点大于父节点
if self._elements[ndx] > self._elements[parent]:
#交换值
self._elements[ndx],self._elements[parent] = self._elements[parent],self._elements[ndx]
#递归在进行比较
self._silfup(parent)
#删除根节点
def extract(self):
#先判断是否还有值
if self._count <= 0:
raise Exception('empty')
#取出根节点
value = self._elements[0]
#长度减一
self._count -= 1
#把最后一个节点上的值,赋值给根节点
self._elements[0] = self._elements[self._count]
#调用_siftdown 函数
self._siftdown(0)
#返回根节点的值
return value
#通过siftdown的方法满足最大堆的特点
def _siftdown(self,ndx):
#计算左孩子的下标
left = 2 * ndx + 1
#3计算右孩子的下标
right = 2 * ndx + 2
langest = ndx
#首先左节点下标要小于当前的数组的长度,其次左孩子大于根节点,再其次左孩子大于右孩子
if (left < self._count and
self._elements[left] >= self._elements[langest] and
self._elements[left] >= self._elements[right]):
#把值左孩子的下标,赋值给langest
langest = left
#右孩子下标小于数组的长度,其次右孩子大于左孩子
elif right < self._count and self._elements[right] >= self._elements[langest]:
#把右孩子的下标赋给langest
langest = right
#当左孩子,或者是右孩子的不等于根下标
if langest != ndx:
#根节点和左孩子或者右孩子交换位置
self._elements[ndx],self._elements[langest] = self._elements[langest],self._elements[ndx]
#递归调用siftdown方法,,从当前节点开始重新判断
self._siftdown(langest)
#######################################################################
#通过最大堆实现一个优先队列
#######################################################################
#优先队列
class Priority_Queue(object):
#初始化方法
def __init__(self,maxsize = None):
#定义最大长度
self.maxsize = maxsize
#实例化这个最大堆的实现
self._maxheap = MaxHeap(maxsize)
#添加数据
def push(self,priority,value):
entry = (priority.value)
self._maxheap.add(entry)
def pop(self,with_priority = False):
entry = self._maxheap.extract()
if with_priority:
return entry
else:
return entry[1]
def is_ampty(self):
return len(self._maxheap) == 0
# 实现一个堆排序
def heapsort_reverse(array):
# 数组长度
length = len(array)
# 实例化这个堆排序方法,初始化最大长度
maxheap = MaxHeap(length)
# 遍历数组
for i in array:
# 调用maxheap的add方法
maxheap.add(i)
# 创建新的集合
res = []
# 循环最大长度
for i in range(length):
# 删除堆中数据,添加到新的数组中
res.append(maxheap.extract())
# 返回新的数组
return res