Python堆排序

Python堆排序

思想
  • 构建堆

  • 输出堆

分析
1. 构建堆
  • 从底向上,从右往左调整堆

    • 示例:图中节点表示索引

      在这里插入图片描述

      调整顺序为:3 --> 2 --> 1 --> 0

    • 调整索引范围:[0, n//2-1]n为数组长度

  • 每次调整,从上往下(构建大根堆)

    • 比较父节点与子节点的最大值,将父节点与子节点的最大值交换

      父节点索引:father

      子节点索引:father*2+1father*2+2

      注意:边界处理

      • n为偶数,父节点最大索引father=n//2-1时,子节点最大索引可达father*2+2
      • n为奇数,父节点最大索引father=n//2-1时,子节点最大索引可达father*2+1
    • 示例:调整节点 1 时(构建大根堆)

      在这里插入图片描述

      注意:该示例只是为了说明思想,由于构建堆是从底向上,从右往左构建,因此,若实际中遍历至该示例的节点 1 时,该节点以下的各节点已构成堆。

2. 输出堆
  • 将堆顶元素与堆尾元素交换,更新堆尾前一节点为新的堆尾,调整堆顶至堆尾的各元素,调整方式同上

  • 不断执行上一步,直至输出所有元素

  • 示例

    在这里插入图片描述

  • 最终数组排序即为升序排列(大根堆的情况下)

附代码(Python3)
def heap_sort(nums):
    n = len(nums)
    # 构建大根堆
    for i in range(n//2-1, -1, -1):         # 从底向上,从右往左
        heap_adjust(nums, i, n-1)            # 调整(堆,父节点,堆尾节点)
        
    # 输出大根堆(即升序)
    for i in range(n-1, -1, -1):
        nums[0], nums[i] = nums[i], nums[0]  # 交换堆顶与堆尾元素,交换后的堆尾元素即输出值
        heap_adjust(nums, 0, i-1)            # 调整(堆,堆顶,新堆尾节点)
        
def heap_adjust(nums, father, end):
    # 从上往下调整
    child = father*2+1       # 初始孩子节点                        
    while child <= end:
        # 选择孩子节点中较大者
        if child<end and nums[child+1]>nums[child]:
            child += 1
        # 若孩子节点大于父亲节点,则交换,更新孩子节点为新的父节点,寻找其新的孩子节点
        # 否则跳出
        if nums[child] > nums[father]:
            nums[father], nums[child] = nums[child], nums[father]
            father = child
            child = father*2+1
        else:
            break
li = [50, 16, 30, 10, 60, 90, 2, 80, 70]
heap_sort(li)
li
[2, 10, 16, 30, 50, 60, 70, 80, 90]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值