8.python实现基数排序和堆排序

基数排序

from typing import List


def radix_sort(arr: List) -> List:
    """
    基础排序
    核心思想: 一共有0-9为数字的桶,一共10个,一共循环数组中最大数的位数次(如最大数是1000则是4次个十百千位分别循环),
    每一次循环依次从数中取出个、十、百、千、万...位数上的数值放到对应的桶中,如果该位上没有数字补零,
    然后依次从0-9桶中取出组成一个新的临时数组作为下一次循环的输入,
    一直到循环到最高位,最后依次得到的结果即是有序。(此法只适合正整数的排序)
    :param arr:
    :return:
    """
    max_val = max(arr)
    max_len = len(str(max_val))

    for i in range(0, max_len):
        # 0-9的数字桶
        bracket = [[] for _ in range(10)]
        for j in range(len(arr)):
            num = int(arr[j] / 10 ** i % 10)
            bracket[num].append(arr[j])
        arr = []
        for items in bracket:
            if items is not []:
                arr.extend(items)
    return arr


if __name__ == '__main__':
    arr = [4, 1, 5, 7, 6, 15, 55, 72, 666]
    arr2 = radix_sort(arr)
    print(arr2)
    print(arr)

堆排序

def heap_sort(arr):
    """
    堆排序
    :param arr:
    :return:
    """
    # 创建大顶堆
    # 此时我们从最后一个非叶子结点开始
    # (叶结点自然不用调整,最后一个非叶子结点 arr.length/2-1=5/2-1=1,也就是下面的6结点),
    # 从左至右,从下至上进行调整
    length = len(arr)
    for i in range(length // 2 - 1, -1, -1):
        adjust_heap(arr, i, length)
    for j in range(length - 1, -1, -1):
        arr[0], arr[j] = arr[j], arr[0]
        adjust_heap(arr, 0, j)


def adjust_heap(arr, index, length):
    """
    调整成大顶堆
    :param arr:
    :return:
    """
    temp = arr[index]
    # 这里之所以用 步长为 2*k+1 是因为 需要找到当前节点的左子节点 下一次循环就是找在下一个左子节点 但是最终不能超过数组长度
    k = 2 * index + 1
    while k < length:
        # 找到 左右子节点中最大的一个
        if k + 1 < length and arr[k] < arr[k + 1]:
            k += 1
        # 判断 父节点跟最大子节点的大小 如果子节点大交换位置构成大顶堆
        # 上边走完之后 指针已经指向了子节点中最大的一个
        # 再判断子节点中最大的一个元素和当前父节点的大小 如果比父节点大 则交换数据 并交换指针!!!
        if temp < arr[k]:
            arr[index] = arr[k]
            # 因为交换了位置需要把新的顶点重新赋值给index
            index = k
        else:
            break
        k = 2 * k + 1
    arr[index] = temp


if __name__ == '__main__':
    arr = [-1, 1, 3, 7, 9, 55, 1, -1]
    heap_sort(arr)
    print(arr)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值