数据结构 - 堆排序(Python 实现,详细注释)

数据结构 - 堆排序(Python 实现)

  • 完全二叉树

    假设二叉树的深度为 h h h,除第 h h h 层外,其它各层 1 ~ ( h − 1 ) 1~(h-1) 1(h1) 的节点数都达到最大个数,第 h h h 层所有的节点都 连续 集中在最左边,这就是完全二叉树。

    完全二叉树可用数组表示。

  • 堆分为大顶堆(节点元素值大于左右子节点元素值)和小顶堆(节点元素值小于左右子节点元素值)。

  • 堆排序

    堆排序属于选择排序,不稳定排序,时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

    在排序后,存储在数组中的元素成有序序列。

    降序使用小顶堆(每次都将第 i i i 小元素置于数组倒数第 i i i 位置);
    升序使用大顶堆(每次都将第 i i i 大元素置于数组倒数第 i i i 位置)。


相关详细理论可参阅 堆排序理论介绍


Python 代码实现
def max_heap(arr, length):
    """
    每一遍的最大堆排序 max_heap 都会选出最大的元素,并置于堆顶
    :param arr: 传入待排数组的指针
    :param length: 当前需要排序的数组长度
    :return: None
    """

    # 每次从最后一个非叶子结点开始
    start = length // 2 - 1

    # 因为是从最后一个结点开始,所以以后每次只需将目标根元素索引减一
    # 即相当于从右向左,从下至上遍历了所有非叶子结点
    for root in range(start, -1, -1):

        # 当前非叶子结点(下称:根节点)的左子节点与右子节点的索引
        left = root * 2 + 1
        right = left + 1

        # 比较左子节点与右子节点,将二者中的最大值与根节点比较
        if right < length:
            temp = left if arr[left] > arr[right] else right
        else:
            temp = left

        # 将最大值与当前根节点交换
        if arr[root] < arr[temp]:
            arr[root], arr[temp] = arr[temp], arr[root]


def sort_heap(arr):

    length = len(arr)

    # 对待排数组构建初始堆,此时最大值已经处于堆顶
    max_heap(arr, length)

    # 对长度len-1的待排数组进行堆性质维护
    for l in range(len(arr)-1, -1, -1):

        # 之所以长度len-1,是因为每次都已经将最大值置于序列尾部
        # 已经处于尾部的最大值不要在进行排序
        arr[l], arr[0] = arr[0], arr[l]

        # 对长度len-1的待排序列进行堆排序
        max_heap(arr, l)
        print(arr)


if __name__ == '__main__':

    from random import randint

    arr = [randint(0, 25) for _ in range(5)]

    print("init:", arr)
    sort_heap(arr)
    print("end:", arr)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值