Python 堆排序

Python 堆排序

叶子节点数: n0=n2+1 n 0 = n 2 + 1 ,下标表示度
平均深度h: N N ,N表示节点个数
完全二叉树:1到k-1层,都是满的二叉树,第k层,叶节点集中在左边

i从0开始,
子节点找父节点:

int( (i-1) / 2 )
或(区别在于i=0,上面为0,下面取值为-1;一般都行,不会父节点去找父节点)
(i-1)//2

父节点找子节点:

左节点:2 * i + 1
右节点:2 * i + 2

最大堆:max_heap,节点值 >= 子节点
最小堆:min_heap,节点值 <= 子节点

堆排序:不稳定,时间复杂度O(nlogn),空间复杂度最好O(1)

构建堆

def max_heap(L, i, k):
    # k控制当前L的取值范围,配合原地堆排序
    # i 表示度=2的节点(相对父节点),
    # 初始为最后一个度=2的节点,值(len(L)-1)//2
    # 二叉树,最后一个度=2的节点,也就是最后一个节点n的父节点,(n-1)//2
    l, r = 2*i+1, 2*i+2
    maxN = i  # 默认父节点值最大
    h = len(L[:k])-1
    if l < h and L[maxN] < L[l]:
        # l<h, 表示左节点存在;然后和最大值比较
        maxN = l
    if r <= h and L[maxN] < L[r]:
        # r<=h, 表示右节点存在;然后和最大值比较
        maxN = r
    if maxN != i:
        # 表示最大节点不是父节点
        # 交换父节点、最大节点的值
        L[maxN], L[i] = L[i], L[maxN]
        # 因为从下到上建立堆,下面的堆都已经建立好,但现在和父节点交换,
        # 可能因为父节点较小,会打破已经建立好的下面的堆
        # 不确定交换后得到的左/右节点,和其子节点还能满足最大堆性质
        max_heap(L, maxN, k)

def build_heap(L, k):
    # k,默认为len(L)长度,用来控制原地堆排序算法的,只构建堆时不需要
    # 取度为2的最后一个节点,父节点
    # 因为最后一个节点为len(L),所以其父节点为(len(L)-1)//2
    # 完全二叉树,也就是最后一个度为2的节点
    ii = (len(L[:k])-1)//2
    while ii>=0:
        # 从最后一个度=2的父节点,到根节点ii=0
        max_heap(L, ii, k)
        ii -= 1  # 从下到上建立堆

堆排序

def heap_sort(L):
    build_heap(L, len(L))  # 建立最大堆
    for i in range(len(L)-1, 0 ,-1):
        # i初始值为最后一位数值,循环最后取值i=1
        # 将第一位数也就是最大值和最后一位交换
        L[0], L[i] = L[i], L[0]
        # 对L[:i],取不到i,进行构建最大值,
        # 然后再次循环交换第一位数和当前最后一位i
        build_heap(L, i)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值