Ctrl+f搜关键词,搜不到找其他博客,下面肯定没有
时间复杂度
冒泡排序
相邻两个数比较,前面比后面大,则交换位置
选择排序
通过确定一个 Key 最大或最小值,再从带排序的的数中找出最大或最小的交换到对应位置。再选择次之。
插入排序
先得到第一个数,下一个数再根据大小排在序列内,以此类推
希尔排序
#分为有序区和无序区,无序区第一个和有序区最后一个比较,再和有序区倒数第二个比较,以此类推,知道找到位置,然后整体后移一位
def shellSort_2(nums):
n = len(nums) # 数组的长度
# 设定一个增量gap
gap = n // 2
while gap >= 1:
# 分组
for i in range(gap, n):
# i = 5, curNum=43, idx = 0
# [43, ..., 44, ...., 85]
# i=7, curNum=7, idx=2
# [..., 7, ... 59, ...]
curNum = nums[i] # 当前要插入的无序区的元素的值
idx = i - gap # 当前元素所在小组的有序区的最后一个元素的索引
while idx >= 0 and curNum < nums[idx]:
nums[idx+gap] = nums[idx]
idx -= gap
nums[idx+gap] = curNum
gap //= 2 # 缩小增量
# gap=5 [44, 43, 85], [12, 94], [59, 7], [36, 35], [62, 52]
test = [44, 12, 59, 36, 62, 43, 94, 7, 35, 52, 85]
shellSort_2(test)
print(test)
快排
partition函数得出所有值中大小居中的值,左右分别大于和小于这个值,再在左边和右边重复该操作
def partition(nums, left, right):
pivot = nums[left] # 区域的第一个元素作为基准值
while left < right:
# 挖坑,填坑
while left < right and nums[right] > pivot:
right -= 1
nums[left] = nums[right]
while left < right and nums[left] <= pivot:
left += 1
nums[right] = nums[left]
nums[left] = pivot # 基准值的正确位置
return left
def quickSort(nums, left, right):
if left >= right:
return
# 分区 --> 分好区之后的基准值的索引
pivot_idx = partition(nums, left, right)
# print(nums, pivot_idx)
# 左边的区域, left->pivot_idx-1
quickSort(nums, left, pivot_idx-1)
# 右边的区域, pivot_idx+1->right
quickSort(nums, pivot_idx+1, right)
test = [44, 12, 59, 36, 62, 43, 94, 7, 35, 52, 85]
quickSort(test, 0, len(test)-1)
print(test)
归并排序
#吧列表无限对半分,直到剩下左右各一个数据,判断大小并排序进有序数组,合并后由左右边的数组从第一个数据开始比较并有序放入数组
def merge(left, right):
# 最终返回一个合并好的有序的数组
# 定义两个变量,分别代表当前left与right的未添加进有序数组的第一个元素
left_idx, right_idx = 0, 0
res = [] # 有序数组
while left_idx < len(left) and right_idx < len(right):
# 左边数组的元素小于右边数组
if left[left_idx] <= right[right_idx]:
# 把左边元素添加到有序区中
res.append(left[left_idx])
# 索引往后移
left_idx += 1
else:
# 把右边元素添加到有序区中
res.append(right[right_idx])
# 索引往后移
right_idx += 1
res += right[right_idx:] # 把剩余的未添加的元素全部添加到有序数组后面
res += left[left_idx:] # 为什么可以直接添加?因为left,right本身就是一个有序数组
# 如果说left_idx走完了,right还剩一些元素,说明right剩下的元素全部都比有序数组的最后一个元素要大
return res
def mergeSort(nums):
# 分
# 数组不能再分了
if len(nums) <= 1:
return nums
mid = len(nums) // 2 # 求出数组的中间位置
print(nums[:mid], nums[mid:])
left = mergeSort(nums[:mid]) # 左边的数组
right = mergeSort(nums[mid:]) # 右边的数组
# 合
return merge(left, right)
test = [44, 12, 59, 36, 62, 43, 94, 7, 35, 52, 85]
test = mergeSort(test)
print(test)
# 时间复杂度 O(nlogn)
桶排序
#根据最小值确定桶的大小和个数,将所有数放入对应桶中,然后桶中数字依次比较,代替比自己大(小)的第一个数,因为每个数都有一次代替机会所以
def bucketSort(nums, size=5):
# 根据数组的最大值与最小值确定要申请的桶的数量
maxVal = max(nums) # 最大值
minVal = min(nums) # 最小值
bucketCount = (maxVal - minVal) // size + 1 # 桶的数量
buckets = [[] for _ in range(bucketCount)] # 申请桶
for num in nums:
idx = (num - minVal) // size # num应该在哪个桶中,索引为idx
n = len(buckets[idx]) # 求出当前桶中的元素个数
i = 0
# 找到第一个比num要大的元素
while i < n and buckets[idx][i] <= num:
i += 1
buckets[idx].insert(i, num)
print(buckets)
# 合并桶
nums.clear()
for bucket in buckets:
nums.extend(bucket) # 将每个桶中的元素放到nums中
test = [1, 2, 3, 3, 3, 3, 3, 99]
bucketSort(test)
print(test)