堆排序

堆排序(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']


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WangZhe0912

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值