堆排序

算法思想:

 

堆:数据结构是一种数组对象,它可以被视为一种完全二叉树。Length[A]是数值中元素的个数,heap-size[A]是存放在A中堆的元素个数。就是说,A[1...heapSize[A]]中的元素属于堆,其后面的元素不属于堆。

 

大顶堆:除了叶子节点外,每个父节点的值均大于左右子节点的值。小顶堆类似。

 

堆排序时,首先需要将输入数组构造成一个最大堆:如代码中Build_MaxHeap函数。该函数从最底层的父节点开始不断调整堆,直到根节点。调整堆函数参见Max_Heapify,某个节点经该函数调整后,以该节点为根的子树都会保持着大顶堆的性质。如此就可以构建成一个大顶堆。之后,由于树根是堆中元素最大的值,我们交换树根和堆中最后一个元素的值,并去掉最后一个元素。然后调整交换后的堆,使其仍为大顶堆,如此循环。我们就可以得到正确的顺序

 

算法代码:

#filename Heap_Sort.py 堆排序

#保持堆的性质,使堆成为最大堆
def Max_Heapify(srcArray, i, heapSize):
    # srcLength = len(srcArray)
    #获得左右的子节点的位置
    leftChildPos = i*2 + 1
    rightChildPos = (i+1)*2
    largest = i

    #调整堆
    if leftChildPos < heapSize and srcArray[leftChildPos] > srcArray[i]:
        largest = leftChildPos
    if rightChildPos < heapSize and srcArray[rightChildPos] > srcArray[largest]:
        largest = rightChildPos
    if largest != i:
        temp = srcArray[i]
        srcArray[i] = srcArray[largest]
        srcArray[largest] = temp
        Max_Heapify(srcArray, largest, heapSize)
        
######################end##########################
#建堆
def Build_MaxHeap(srcArray):
    srcLength = len(srcArray)
    for i in range((srcLength-1)/2, -1, -1):
        Max_Heapify(srcArray, i, srcLength)
        
#############################################
#堆排序
def Heap_Sort(srcArray):
    Build_MaxHeap(srcArray)
    heapSize = len(srcArray)
    for i in range(len(srcArray)-1, 0, -1):
        temp = srcArray[i]
        srcArray[i] = srcArray[0]
        srcArray[0] = temp
        heapSize -= 1
        Max_Heapify(srcArray, 0, heapSize)
        
###################################################
#测试
if __name__ == '__main__':
    srcArray = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]
    print 'Before Sorted'
    print srcArray
    Build_MaxHeap(srcArray)
    Heap_Sort(srcArray)
    print 'After Sorted'
    print srcArray


算法结果:

 

算法复杂度:O(nlgn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值