堆排序

来源:互联网 发布:网络流行照片 编辑:程序博客网 时间:2024/06/07 06:44

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。

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

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

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

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

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

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

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

Python的代码实现如下:

# -*- coding: utf-8 -*-#用列表表示一个堆,其中列表中索引为0的位置为空。从索引1开始存放元素。def parent(i):    #在堆中,某个节点的父节点为其索引值整除2。例如索引为4的父节点的索引为2。索引为9的父节点的索引为4。    return i/2def left(i):     #某个节点的左子节点的索引为i*2    return i*2def right(i):    #某个节点的右子节点的索引为i*2+1    return i*2+1class 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']


0 0
原创粉丝点击