排序算法07-堆排序 Python实现

堆排序是一种基于比较的排序算法,通过构建大根堆或小根堆来实现。本文主要介绍如何使用Python实现大根堆,并详细解释了堆排序的三个步骤:构造二叉堆、交换根节点与末尾节点并删除、重新调整堆。推荐参考一个动态展示堆排序过程的网站,对于理解和实现堆排序非常有帮助。

堆分为大根堆和小根堆

大根堆是一颗完全二叉树,且根节点大于所有子节点,每棵子树也是大根堆

堆排序要做的就是(1)先把列表构造成一棵二叉树,然后将这棵二叉树调整成大根堆

(2)然后将根节点与最后一个子节点交换,删掉最后一个子节点(并不是真的删掉,只是下次排序不带它)

(3)将剩下的二叉树重新调整成大根堆

重复(2)(3)直到堆为空

关于构造大根堆和调整大根堆的过程可以参考这个神奇的网站

https://visualgo.net/en/heap?slide=1

它可以动态展示大根堆得构造过程,堆排序得过程,,以及添加新节点后重新调整为大根堆的过程,仔细看几遍,对理解堆排序很有帮助,配合代码注释食用更佳

 

 

lists = [9, 78, 54, 91, 86, 53, 88, 66, 46, 15]


"""自下而上构造大根堆"""


def create_heap(a):
    f = len(a) // 2 - 1
    for i in range(f, -1, -1):
        """找到左孩子"""
        left_child = 2 * i + 1
        """如果存在右孩子,并且大于左孩子,指针指向右孩子"""
        if left_child + 1 < len(a) and a[left_child] < a[left_child + 1]:
            left_child = left_child + 1
        """如果较大的孩子比父亲大,则交换"""
        if a[left_child] > a[i]:
            swap(a, left_child, i)
            recreate_heap(a, left_child, len(a))


"""自上而下调整大根堆"""


def recreate_heap(a, parent, end):
    left_child = parent*2+1
    if left_child > end:
        return
    if left_child+1 < end and a[left_child] < a[left_child+1]:          #len(a) -> end
        left_child = left_child+1
    if a[left_child] > a[parent]:
        swap(a, left_child, parent)
        recreate_heap(a, left_child, end)     #如果父亲比孩子小,交换完之后,以孩子为节点的子树很可能也需要调整


"""堆排序"""


def heap_sort(a):
    """先构造大根堆"""
    create_heap(a)
    """将根节点与第i个节点交换,调整大根堆"""
    for i in range(len(a)-1, -1, -1):
        swap(a, 0, i)
        recreate_heap(a, 0, i-1)
        print(a)


"""交换两个数"""


def swap(list, a, b):
    temp = list[a]
    list[a] = list[b]
    list[b] = temp

heap_sort(lists)


print(lists)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值