堆排序(python实现)

对于堆的概念以及它的一些基本操作,请参见我的上一篇博客

利用堆实现排序的简单思路是,利用堆顶元素总是最大或者最小的性质,每次弹出一个元素,直到堆空,则弹出元素形成的序列是有序的。但是为了节约存储空间,我们直接将弹出的元素放在原堆内存的后面,这样形成的最后形成的有序数组的顺序是和堆中数据的顺序性是相反的(若是小根堆,排序后是由大到小的;若是大根堆,排序后是由小到大的)。代码如下所示

def heap_sort(elems):
    def siftdown(elems,e,begin,end):
        i,j=begin,begin*2+1
        while j<end:
            if j+1<end and elems[j+1]<elems[j]:
                j+=1
            if e<elems[j]:
                break
            elems[i]=elems[j]
            i=j
            j=2*j+1
        elems[i]=e

    end=len(elems)
    for i in range(end//2-1,-1,-1):
        siftdown(elems,elems[i],i,end) #创建堆
    for i in range((end-1),0,-1):
        e=elems[i]
        elems[i]=elems[0]
        siftdown(elems,e,0,i)

以上代码是基于小根堆的排序,其中siftdown函数也在我的上一篇博客中有讲解,是元素下沉的操作。该函数首先从传入的list创建堆。然后依次取下堆顶的元素,放在堆序列中i的位置,i是从堆序列最后位置索引到1依次减小的,每次下沉的范围下限逐渐减小。

测试代码:

elems=[2,5,6,2,5,6,7,3,2,3,6]
heap_sort(elems)
print(elems)#[7, 6, 6, 6, 5, 5, 3, 3, 2, 2, 2]

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值