冒泡排序
算法步骤:
- 比较相邻的元素,如果第一个大于第二个则交换
- 从左往右遍历一遍,重复第一步,可以保证最大的元素在最后面
- 重复上述步骤,可以得到第二大、第三大、…
时间复杂度: O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( 1 ) O(1) O(1),稳定
n = int(input())
a = list(map(int, input().split()))
for i in range(1, n):
for j in range(0, n - i):
if a[j] > a[j + 1]:
a[j], a[j + 1] = a[j + 1], a[j]
print(' '.join(map(str, a)))
选择排序
算法步骤:
- 从左往右找到最小的元素,放在起始位置
- 重复上述步骤,依次找到第 2 2 2、第 3 3 3 小元素…
时间复杂度: O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( 1 ) O(1) O(1),稳定
n = int(input())
a = list(map(int, input().split()))
for i in range(n - 1):
min_num = a[i]
idx = i
for j in range(i + 1, n):
if a[j] < min_num:
min_num, idx = a[j], j
a[i], a[idx] = a[idx], a[i]
print(' '.join(map(str, a)))
插入排序
算法步骤:
- 第一个元素看做已排序,从左往右遍历每一个元素:
- 在已排序元素中从后往前扫描,如果当前元素大于新元素,则该元素移动到后一位
- 重复第二步直至找到小于等于新元素则停止
- 将上述步骤看做摸牌,每次摸一张牌从后往前判断是否可以插入
时间复杂度: O ( n 2 ) O(n^2) O(n2),空间复杂度 O ( 1 ) O(1) O(1),不稳定
n = int(input())
a = list(map(int, input().split()))
for i in range(1, n):
temp = a[i]
idx = 0
for j in range(i - 1, -1, -1):
if a[j] > temp:
a[j + 1] = a[j]
else:
idx = j + 1
break
a[idx] = temp
print(' '.join(map(str, a)))
快速排序
算法步骤:
- 找一个基准值 x x x
- 把列表分成三部分:小于等于 x x x 的数字, x x x,大于 x x x 的数字
- 左半部分和右边部分递归使用该策略
时间复杂度: O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n)),空间复杂度 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n)),不稳定
def partition(a, left, right):
idx = left + 1
for i in range(left + 1, right + 1):
if a[i] <= a[left]:
a[i], a[idx] = a[idx], a[i]
idx += 1
a[left], a[idx - 1] = a[idx - 1], a[left]
return idx - 1
def quicksort(a, left, right):
if left < right:
mid = partition(a, left, right)
quicksort(a, left, mid - 1)
quicksort(a, mid + 1, right)
n = int(input())
a = list(map(int, input().split()))
quicksort(a, 0, len(a) - 1)
print(' '.join(map(str, a)))
归并排序
算法步骤:
- 先把数组分成两部分
- 每部分递归处理变成有序
- 将两个有序列表合并起来
时间复杂度: O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n)),空间复杂度 O ( n ) O(n) O(n),稳定
def Merge(A, B):
result = []
while len(A) != 0 and len(B) != 0:
if A[0] <= B[0]:
result.append(A.pop(0))
else:
result.append(B.pop(0))
result.extend(A)
result.extend(B)
return result
def MergeSort(A):
if len(A) < 2:
return A
mid = len(A) // 2
left = MergeSort(A[:mid])
right = MergeSort(A[mid:])
return Merge(left, right)
n = int(input())
a = list(map(int, input().split()))
a = MergeSort(a)
print(' '.join(map(str, a)))
桶排序
利用函数映射关系,将输入数据分到有限的桶里,然后每个桶分别排序:
- 初始化 K K K 个桶
- 遍历数据,将数据放入对应桶中
- 每个桶单独排序
- 各个桶的数据拼接起来
为了避免过多元素进入同一个桶:
- 优化映射方法,使得桶内元素均匀
- 增加桶的数量,利用时间换空间
数据如果服从均匀分布,则利用桶排序效率越高
桶内部排序算法可以采用其他简单的排序算法
def BucketSort(a, bucketcount):
minvalue, maxvalue = min(a), max(a)
bucketsize = (maxvalue - minvalue + 1) // bucketcount
res = [[] for i in range(bucketcount + 1)]
# 把所有元素放到对应桶中
for x in a:
idx = (x - minvalue) // bucketsize
if idx >= bucketcount:
idx = bucketcount - 1
res[idx].append(x)
# 每个桶单独排序
ans = []
for res_x in res:
res_x.sort()
ans.extend(res_x)
return ans
n = int(input())
a = list(map(int, input().split()))
a = BucketSort(a, min(10000, n))
print(' '.join(map(str, a)))
参考博客内容:排序