您的位置:首页 > 其它

堆排序

2016-09-03 21:43 141 查看
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。

可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。

在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

堆排序首先将待排序的数组存入堆中,并将堆构造为最大/最小堆。再依次从堆中取出堆顶元素,从而得到有序数组。

构造堆时,所用的方法为从最底层有子节点的节点开始依次向上处理。

取出顶元素恢复堆时则是先将末尾元素与顶元素交换位置,在对顶元素进行下沉处理即可。

堆排序是不稳定排序。即相同的元素再经过堆排序后,其先后位置可能发生变化。

堆排序的时间复杂度为N*logN。

Python的代码实现如下:

# -*- coding: utf-8 -*-
#用列表表示一个堆,其中列表中索引为0的位置为空。从索引1开始存放元素。
def parent(i):    #在堆中,某个节点的父节点为其索引值整除2。例如索引为4的父节点的索引为2。索引为9的父节点的索引为4。
return i/2

def left(i):     #某个节点的左子节点的索引为i*2
return i*2

def right(i):    #某个节点的右子节点的索引为i*2+1
return i*2+1

class Heap:     #堆的数据结构类
def __init__(self, heapList=[None]):   #对堆进行初始化。没有给堆初始列表时,初始化为仅包含一个None元素的列表。
self.heapList = [None] + heapList    #有初始化列表时,堆列表为初始化列表前插入None元素

def max_heapfy(self, i):   #表明对i节点进行最大堆恢复
if (i*2) > self.length-1:   #该元素没有子节点时
maxIndex = i
elif (i*2+1) > self.length-1:   #该元素只有左节点时
maxIndex = left(i)
elif self.heapList[left(i)] > self.heapList[right(i)]:   #该元素同时有左右节点,且左节点的值大于右节点时
maxIndex = left(i)
else:    #该元素同时有左右节点,且左节点的值小于右节点时
maxIndex = right(i)
if self.heapList[i] < self.heapList[maxIndex]:   #当其子节点值大于其节点值时:
self.heapList[i], self.heapList[maxIndex] = self.heapList[maxIndex], self.heapList[i]
#交换其子节点的值和其值
self.max_heapfy(maxIndex)  #并对其子节点进行最大堆化

def build_max_heap(self):      #构建最大堆
self.length = len(self.heapList)    #计算堆的大小(包含第一个空元素)
for i in range(self.length/2, 0, -1):  #从包含子节点的节点开始依次向上遍历
self.max_heapfy(i)

def insert(self, k):   #向堆内插入元素
self.length += 1    #堆的规模加1
self.heapList.append(float("-inf"))   #向堆内插入一个负无穷的数
self.increase_key(self.length, k)   #增加元素

def maxinum(self):    #查询堆内最大元素,即为索引为1的元素值。
return self.heapList[1]

def extract_max(self):    #弹出堆内最大元素。
maxValue = self.heapList[1]    #取得最大元素值
self.heapList[1] = self.heapList[self.length]   #将末尾元素移至堆头
del self.heapList[self.length]  #删除末尾元素
self.length -= 1  #将堆的规模减1
self.max_heapfy(1)   #对堆顶元素最大堆化
return maxValue

def increase_key(self, x, k):   #增加元素
self.heapList[x] = k   #将新增的负无穷位置赋予插入值
while x > 1 and self.heapList[parent(x)] < self.heapList[x]: #当元素索引大于1且其值大于其父节点值
self.heapList[parent(x)], self.heapList[x] = self.heapList[x], self.heapList[parent(x)]
#交换其值和其父节点的值
x = parent(x)  #继续对其父节点进行判断

def show(self):  #展示堆
print "the length of queue is", self.length - 1
print "the heapList is", self.heapList[1:]

def heapSort(unsortedList):
heap = Heap(unsortedList)   #将乱序列表转换为堆
heap.build_max_heap()       #将堆构建为最大堆
print heap.heapList
print "*************heap has been build up*********"
for i in range(len(unsortedList), 1, -1):
heap.heapList[i], heap.heapList[1] = heap.heapList[1], heap.heapList[i]  #将末尾节点与根节点进行交换,
#交换完成后,i位置的节点为当前堆中最大的元素。即每次循环中得到的i索引的元素为已有序的列表。
heap.length -= 1   #未排序的堆的规模减小1
heap.max_heapfy(1)    #此时,根节点不满足最大堆的要求,需要对堆进行最大堆恢复
return heap.heapList[1:]

if __name__ == '__main__':
list1 = [3,2,4,6,7,5,1,8,10,9]
list2 = ["wang", "zhe", "tian", "jin", "da", "xue"]
ordered_list1 = heapSort(list1)
ordered_list2 = heapSort(list2)
print ordered_list1             #[2, 3, 4, 5, 6, 7]
print ordered_list2             #['da', 'jin', 'tian', 'wang', 'xue', 'zhe']
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: