O(n)时间复杂度建堆 &堆排序

该方法假设子树已经是堆,(这要求在访问结点之前,先访问子结点) 比较简单的方法是 从数组的较大序号到较小序号,实际上叶子结点没有子结点,因此从第一个分支结点开始访问

# encoding=utf-8

import logging

l = [i for i in range(10, 0, -1)]

def swap(a,b):
    a=a^b
    b=a^b
    a=a^b
    return a,b

def shiftdown(l, i):
    logging.info("start shifdown %s" % (l[i]))
    pos = i
    # 不需要访问叶子结点
    while pos < int(len(l)/2):
        left = 2*pos + 1
        # 找出子结点中值较小的结点的索引值
        if 2*(pos+1) < len(l) and l[2*pos+1] > l[2*pos+2]:
            left += 1
        if l[pos] > l[left]:
            # swap the element
            l[pos], l[left] = swap(l[pos], l[left])
            pos = left
        else:
            break

def heap_(l):
    le = len(l)
    for i in range(int(le/2)-1, -1, -1):
        shiftdown(l, i)

r = []
def sort_(l):
    end = len(l) - 1
    while end > 0:
        l[end], l[0] = swap(l[end], l[0])
        r.append(l.pop())
        shiftdown(l, 0)
        end -= 1
    r.append(l.pop())
heap_(l)
print (l)
sort_(l)
print(r)

最终输出

[1, 2, 4, 3, 6, 5, 8, 10, 7, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值