其他排序算法及其python代码实现

一些其他的排序算法

希尔排序

时间复杂度随切片的变化而变化

思路

首先取一个整数d1=n/2,将元素分为d1分组,每组相邻元素之间距离为d1,每组进行插入排序,然后取第二个整数d2=d1/2,重复上述分组排序过程,知道di=1
例如这个列表长度为9,所以d1=4,并分组
在这里插入图片描述
在这里插入图片描述
然后5 3 8,7 1,4 2,6 9分别进行插入排序
在这里插入图片描述
然后d2=2,并分组
在这里插入图片描述
然后3 2 5 4 8,1 6 7 9分别进行插入排序
在这里插入图片描述
然后d3=1
在这里插入图片描述
对整个列表进行插入排序
在这里插入图片描述

代码实现

gap版插入排序

只需将原来的插入排序的所有1改成gap

def insert_gap_sort(li,gap):
    for i in range(gap,len(li)):
        tmp = li[i]
        j = i - gap
        while j >= 0 and li[j] > tmp:
            li[j+gap] = li[j]
            j = j - gap
        li[j+gap] = tmp
    return li
主函数
def shell_sort(li):
    d = len(li) // 2
    while d >= 1:
        insert_gap_sort(li,d)
        d = d // 2
    return li

li = [3,6,4,74,8,2,6,9,3]
print('原列表:',li)
print(shell_sort(li))

在这里插入图片描述

计数排序 时间复杂度:O(n)

已知0-100内的一些数,进行排序

思路

例如1,4,5,7,8,4,2,7,首先得到每个数字出现的次数:
1:1 2:1 4:2 5:1 7:2 8:1
所以排序得到:1 2 4 4 5 7 7 8

代码实现

def count_sort(li,max_count=100):
    count = [0 for _ in range(max_count+1)]
    for val in li:
        count[val] += 1
    li.clear()
    for index,val in enumerate(count): #index是数字 val是出现的次数
        for i in range(val):
            li.append(index)

import random
li = [random.randint(0,100) for _ in range(20)]
print("原列表为:",li)
count_sort(li)
print(li)

在这里插入图片描述

桶排序

桶排序的表现取决于数据的分布
平均情况时间复杂度: O(n+k)
最坏情况时间复杂度: O(n平方k)
空间复杂度: O(nk)

思路

桶排序是对计数排序的改进,如果元素的范围比较大
桶排序就是先把元素分在不同的桶中,再对每个桶中的元素排序

代码实现

def bucket_sort(li,n=100,max_num=10000):
    """
    :param li: 列表
    :param n: 桶的个数
    :param max_num: 范围 最大数
    :return:
    """
    buckets = [[] for _ in range(n)]  #创建桶
    for val in li:
        i = min(val //(max_num // n),n-1)  #用min是为了防止当10000时,val //(max_num // n)为100,超过范围
        buckets[i].append(val)   #把val加到桶里面
        for j in range(len(buckets[i])-1,0,-1):  #反向插入排序
            if buckets[i][j] < buckets[i][j-1]:
                buckets[i][j],buckets[i][j-1] = buckets[i][j-1],buckets[i][j]
            else:
                break
    sorted_li = []
    for buc in buckets:
        sorted_li.extend(buc)
    return sorted_li

import random
li = [random.randint(0,10000) for _ in range(100)]
print("原列表为:",li)
print(bucket_sort(li))

结果较长,没有截全
在这里插入图片描述

基数排序

思路

多关键字排序:现有一个员工表,现要求首先按照薪资排序,然后年龄相同的员工按照年龄排序
先按照年龄进行排序,再按照薪资进行稳定对的排序
那么对于一组数字,也可以看做多关键字排序——>从个位 十位…
时间复杂度: O(nk)
空间复杂度: O(n+k)
k表示最大的数字位数
首先按照个位数字大小入桶
在这里插入图片描述
在这里插入图片描述
然后全部取出
在这里插入图片描述
然后按照十位数字排序
在这里插入图片描述
然后全部取出

在这里插入图片描述

代码实现

def radix_sort(li):
    max_num = max(li)
    it = 0
    while 10 ** it <= max_num:
        buckets = [[] for _ in range(10)]  #每个位数有10种可能
        for val in li:
            digit = (val // 10 ** it) % 10 #依次获取每个数字 相同位数的数字  eg.i=0 就是获取个位数字
            buckets[digit].append(val)  #位数上相同数字的放入同一个桶
        li.clear()
        for buc in buckets:
            li.extend(buc)
        it += 1
    return  li

import random
li = [random.randint(0,100) for _ in range(20)]
print("原列表为:",li)
print(radix_sort(li))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值