算法2 归并,快速 桶排序

归并排序

归并排序就是将数据将要排序的列表进行一分为二,分成两个列表,然后递归分列,当列表分成只有一个数据的数据就开始排序合并
有点像分而治之,分裂成多个列表,然后排序合并

data = [42, 16, 84, 12, 77, 26, 53, 84, 10, 11, 12, 77, 42]


def run1(left, right):
    # print(left, right, end="    ")
    lists = []
    # 当 left 和 right 中有数据的时候就进行循环
    while left and right:
        # 判断一下那个列表中的第一个元素小,弹出最小的元素添加到lists 临时列表中
        nums = left.pop(0) if left[0] < right[0] else right.pop(0)
        lists.append(nums)
    # 判断一下 这两个列表中是否还有数据,
    # 如果有,就把有数据的列表添加到lists 后面,python 中列表是可以进行相加的,相当于列表的拼接
    if left or right:
        lists += left if left else right
    # print(lists)

    return lists


def run2(li):
    if len(li) <= 1:
        return li
    nums = len(li) // 2
    print(li[:nums], li[nums:])
    left = run2(li[:nums])   # 当递归到 li 只有两个数据时, left 数据为 li[0], right 数据为 [1]
    right = run2(li[nums:])
    # 当递归到 li 只要两个数据的时候就可以执行run1方法进行排序合并了
    return run1(left, right)


print(run2(data))


快速排序

快速排序和归并排序有点类似,也是递归将列表进行分列, 不过快速排序的区别是它分列的时候会以列表中某个数据作为基准 num
大于等于这个基准数的,就放到 right 列表中, 小于这个基准数的,就放到 left 列表中,然后进行返回合并

return run(left) + [num] + run[right]

lists = [42, 16, 84, 12, 77, 26, 53, 84, 10, 11, 12, 77, 42, 42]


def run(li):
    if len(li) <= 1:
        return li
    nums = li[0]
    li1, li2 = [], []
    li.remove(nums)
    for i in li:
        if i < nums:
            li1.append(i)
        else:
            li2.append(i)
    print(li1, nums, li2)
    return run(li1) + [nums] + run(li2)


li = run(lists)
print(li)

#  快速排序就是列表中的以某个数据为条件,将大于这个的数据和小于这个的数据分为两个列表,然后在将这两个列表进行相同
# 的操作,当最小或最大的列表进行最后一次递归的时候就可以获取到最小值或最大值了,
# 然后将最小值或最大值和当做条件判断的数据进行相加就可以获取到有序的数据了


桶排序

桶排序就是将数据按大小分给接收对应范围的列表中, 如,创建4个空列表,此时这几个空列表可以看出是桶,我有一个要排序的列表,
这个列表中的数据是1-10之间的数据,通过 (数据 - 列表中最小值) // math.ceil((max_temp - min_temp + 1) / 4桶数)
得到该数据可以放到哪一个桶中,将分完桶的列表进行排序, 如 冒泡,选择,插入… 然后再合并

import math

lists = [42, 16, 84, 12, 77, 26, 53, 84, 12, 77, 42, 42]

def run1(li):
    for i in range(1, len(li)):
        while i > 0:
            # 判断当前循环到的列表下标的值是否大于当前下标-1 的值,如果大于,则会换位置,
            if li[i] < li[i - 1]:
                li[i], li[i - 1] = li[i - 1], li[i]
                # 换完位置后将当前下标-1设置为换位置后的数据,让第二次while循环判断,如果i-1=0了,则证明
                # 当前的这位数是当前for循环中遇到的最大的数了,就可以结束 while 循环了
                i -= 1
            # 如果不大于则结束当前while 因为不需要再判断了
            else:
                break
    return li


def run(li, nums=5):
    if len(li) <= 1:
        return
    max_num = max(li)
    min_num = min(li)
    size = math.ceil((max_num - min_num + 1) / nums)
    # 此时的 size 就是桶的范围

    # 创建桶
    lists = []
    for i in range(nums):
        lists.append([])

    # 将数据分到各自对应的桶中
    for i in li:
        index = (i-min_num) // size    # 由于最大值除以size有可能会超出范围,使用要减去最小值
        lists[index].append(i)

    li = []
    for i in lists:
    # 循环获取桶, 将桶中的数据进行排序,此时我排序用的是插入排序
        i = run1(i)
        li += i
    print(li)


run(lists)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值