import random
# 希尔排序
'''
希尔排序是一种分组插入排序算法
首先取一个整数d1 = n/2,将元素分为d1个组,每组相邻两个元素之间距离为d1,在各组内进行直接插入排序
取第二个整数d2=d1/2,重复上述分组排序过程,直到d1=1,即所有元素在同一组内进行直接插入排序
希尔排序每趟并不使某一些元素有序,而是是整体数据越来越接近有序,最后一趟排序使得所有数据有序
时间复杂度:
由gep决定
'''
def insert_sort_gap(li, gep):
for i in range(gep, len(li)): # i表示摸到的牌的下标
temp = li[i]
j = i - gep
while j >= 0 and li[j] > temp:
li[j + gep] = li[j]
j -= gep
li[j + gep] = temp
def shell_sort(li):
d = len(li) // 2
while d >= 1:
insert_sort_gap(li, d)
d //= 2
li = list(range(1000))
random.shuffle(li)
print(li)
shell_sort(li)
print(li)
print('-------------------------------')
# 计数排序
'''
对列表进行排序,已知列表中的个数范围都在0到100之间。
不适用小数与字符串
消耗大量内存
'''
# 时间复杂度:O(n)
def count_sort(li, max_count=100):
count = [0 for i in range(max_count + 1)]
for val in li:
count[val] += 1
li.clear()
# print(count)
for ind, val in enumerate(count):
for i in range(val):
li.append(ind)
def sys_sort(li):
li.sort()
li = [random.randint(0, 100) for _ in range(1000)]
print(li)
count_sort(li)
print(li)
print('-------------------------')
# 桶排序
'''
通过计数排序改进
首先将元素分在不同的桶中,在对每个桶中的元素排序
桶排序的表现取决于数据的分布,也就是需要对不同数据排序时采取不同的分桶策略
平均时间复杂度 : O(n+k)
最坏时间复杂度:O(n**2*k)
分布不均匀就不快
空间复杂度:o(n*k)
'''
def bucket_sort(li, n=100, max_num=10000):
buckets = [[] for i in range(n)] # 创建桶
for var in li:
i = min(var // (max_num // n), n - 1) # i 表示将var放在第几个桶里
buckets[i].append(var) # 把var加到桶中
# 保持桶内的顺序
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
# 0->0
sorted_li = []
for buc in buckets:
sorted_li.extend(buc)
return sorted_li
li = [32, 13, 94, 52, 17, 54, 93]
# print(li)
li = bucket_sort(li)
print(li)
print('<===============================>')
# 基数排序
# 多关键字排序
'''
先按照年龄进行排序,再按照薪资进行稳定的排序
时间复杂度:
O(kn)
空间复杂度:
O(k+n)
k代表数的位数
线性时间复杂度
'''
# 32 13 94 52 17 54 93
# 个位以及十位判断大小
# 十位作为桶,依次判断桶中的数的大小
def radix_sort(li):
max_num = max(li) # 99->2次 888->3次 10000->5次
it = 0
while 10 ** it <= max_num:
buckets = [[] for i in range(10)]
for var in li:
# 987 it =1
digit = (var // (10 ** it)) % 10
buckets[digit].append(var)
# 分桶完成
li.clear()
for buc in buckets:
li.extend(buc)
# 把数重新写回li
it += 1
li = [32, 13, 94, 52, 17, 54, 93]
# random.shuffle(li)
print(li)
print(',.,.,.,.,.,.,.,.,.,.,.,..')
radix_sort(li)
print(li)
# 习题
# 面试题
'''
给两个字符串s和t,判断t是否为s的重新排列后组成的单词
s='anagram',t='nagaram',return true
s='rat',t='car',return false
'''
'''
给定一个m*n的二维列表,查找一个数是否存在。列表有下列特性:
每行的列表从左到右已经排序好
每一行第一个数比上一行最后一个数大
[
[1,3,5,7],
[10,11,16,20],
[23,30,34,50]
]
'''
'''
给定一个列表和一个整数,设计算法找到两个数的下标,使得两个数之和为给定的数。保证肯定仅有一个结果
例如,列表[1,2,5,4]与目标整数3,1+2=3,结果为(0,1)
'''
希尔排序、计数排序和桶排序及其时间复杂度
最新推荐文章于 2023-09-27 10:51:24 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)