python算法(七)堆排序

python算法(七)堆排序

在这里插入图片描述
如上图, 一个堆应该满足所有的子节点都 不大于(不小于)父节点.
当子节点不大于父节点的时候,称为大顶堆
当子节点不小于父节点的时候,称为小顶堆
堆是一个概念上的名词,在实际的程序中,堆是以列表的形式存在的.
因此,如上的堆对应的列表是60 40 32 20 35 45 20 15 10 5 21 25 42 43

堆排序图示

1.首先要将乱序的列表,排列成堆
原始列表: 2 4 8 3 6 1
排列成堆状图:
在这里插入图片描述
4 < 6
调整成
在这里插入图片描述
2<6<8
调整成
在这里插入图片描述
相应列表: 8 6 2 3 4 1
2. 将堆的根节点与最后一个元素互换位置
1 6 2 3 4 8
然后去掉最后一个元素
重新按上面的步骤,重新排堆,换位置,去掉元素再排堆
直到最后一上元素

代码实现

from random import shuffle
def big_endian(num_list, start, end):
   root = start  # 设置根节点
   child = 2 * root + 1 # 左子节点
   
   # 循环直到没子节点的元素为止
   while child <= end:
        # 比较左右两个子节点的大小,以便与父节点比较
        if child + 1 <= end and num_list[child] < num_list[child + 1]:
           child += 1
           
        # 如果子节点更大,交换父子节点的位置 
        if num_list[root] < num_list[child]:
            num_list[root], num_list[child] = num_list[child], num_list[root]
            # 交换好子节点,会破坏下层节点的堆状,要重新调整子节点的堆装
            root = child
            child = 2 * child + 1      
        else:
            # 如果没有破坏堆状,则继续退出
            break

def heap_sort(num_list):
    first=len(num_list)//2 - 1  # 从最后一个父节点开始构造大顶堆
    for start in range(first, -1, -1):
        big_endian(num_list, start, len(num_list)-1)
    # 不断去掉根节点,然后构造新的大顶堆 直到最到一个元素
    for end in range(len(num_list)-1, 0, -1):
        num_list[0], num_list[end] = num_list[end], num_list[0]
        big_endian(num_list, 0, end -1)
    return num_list

if __name__ == '__main__':
    num_list_demo = [x for x in range(10)]
    shuffle(num_list_demo)
    print(num_list_demo)
    heap_sort(num_list_demo)
    print(num_list_demo)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的章老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值