算法分类
算法实现
1. 插入排序
1.1 直接插入排序
每次将 第 i 位 的数值插入到 前面最合适的位置。
def insert_sort(x):
if not x or len(x) <= 1:
return x
for i in range(1, len(x)):
for j in range(i):
if x[j] > x[i]:
tmp = x[i]
for p in range(i, j, -1):
x[p] = x[p-1]
x[j] = tmp
return x
1.2 希尔排序
将数组拆分成多个子数组,分别进行直接插入排序。
实现过程略。
2. 选择排序
2.1 简单选择排序
每次选择 第 i ~ len(x)-1 位 中最小的值,放在 第 i 位 。
def select_sort(x):
if not x or len(x) <= 1:
return x
for i in range(len(x)-1):
for j in range(i+1, len(x)):
if x[i] > x[j]:
x[i], x[j] = x[j], x[i]
return x
2.2 堆排序
略。
法一:
def build_max_heap(x):
import math
for i in range(math.floor(len(x)/2),-1,-1):
heapify(x,i)
def heapify(x, i):
left = 2*i+1
right = 2*i+2
largest = i
if left < arrLen and x[left] > x[largest]:
largest = left
if right < arrLen and x[right] > x[largest]:
largest = right
if largest != i:
swap(x, i, largest)
heapify(x, largest)
def swap(x, i, j):
x[i], x[j] = x[j], x[i]
def heap_sort(x):
global arrLen
arrLen = len(x)
build_max_heap(x)
for i in range(len(x)-1,0,-1):
swap(x,0,i)
arrLen -=1
heapify(x, 0)
return x
法二:
def one_heap_sort(x, l, r):
if r-l <= 0:
return
if r-l == 1 and x[l] > x[r]:
x[l], x[r] = x[r], x[l]
else:
middle = l + (r-l-1) // 2
one_heap_sort(x, l, middle)
one_heap_sort(x, middle+1, r-1)
if x[middle] > x[r]:
x[middle], x[r] = x[r], x[middle]
if x[r-1] > x[r]:
x[r-1], x[r] = x[r], x[r-1]
# 依次将最大值放到数组的后面
def heap_sort(x):
for i in range(len(x)-1, 0, -1):
# for i in range(len(x)):
one_heap_sort(x, 0, i)
测试用例:
x = [1, 10, 8, 200, 50, 4]
heap_sort(x)
assert x == [1, 4, 8, 10, 50, 200]
3. 交换排序
3.1 冒泡排序
每次通过相邻位的值交换,将 第 0 ~ len(x)-i-1 位 中最大的值,放在 第 len(x)-i-1 位 。
def bubble_sort(x):
if not x or len(x) <= 1:
return x
for i in range(len(x)):
for j in range(1, len(x)-i):
if x[j-1] > x[j]:
x[j-1], x[j] = x[j], x[j-1]
return x
3.2 快速排序
法一:
def quick_sort(x):
if not x or len(x) <= 1:
return x
base = x[0]
left = [ele for ele in x[1:] if ele <= base]
right = [ele for ele in x[1:] if ele > base]
return quick_sort(left) + [base] + quick_sort(right)
法二:
def quick_sort(x, low, high):
if not x or len(x) <= 1 or low >= high:
return x
base, l, r = x[low], low, high
while l < r:
while l < r and x[r] >= base:
r -= 1
x[l] = x[r]
while l < r and x[l] <= base:
l += 1
x[r] = x[l]
x[l] = base
quick_sort(x, low, l-1)
quick_sort(x, l+1, high)
return x
法三:
def quick_sort(x, low, high):
if not x or len(x) <= 1 or low >= high:
return x
queue = [low, high]
while queue:
l, r = queue.pop(0), queue.pop(0)
if l >= r:
continue
i = l - 1
for j in range(l, r):
if x[j] <= x[r]:
i += 1
x[i], x[j] = x[j], x[i]
x[i+1], x[r] = x[r], x[i+1]
queue.extend([l, i, i+2, r])
return x
测试用例:
lst_a = list(range(40))
import random
random.shuffle(lst_a)
print(lst_a)
quick_sort(lst_a, 0, 39)
print(lst_a)
4. 归并排序
def merge(left, right):
res, i, j = [], 0, 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
res.append(left[i])
i += 1
else:
res.append(right[j])
j += 1
res += left[i:] or right[j:]
def merge_sort(x):
if not x or len(x) <= 1:
return x
mid = len(x) // 2
left = merge_sort(x[:mid])
right = merge_sort(x[mid:])
return merge(left, right)
5. 基数排序
略。
算法性能
Note:这里的 log
底数为2
。
- 平均时间复杂度:一般为n2,只有 堆排、快排和归排 是nlogn。
- 空间复杂度:一般为1,只有 堆排 是nlogn,归排 是 n。
- 稳定性:一般都是不稳定的,只有 直接插排、冒泡排、归排和基排 是稳定的。
计算复杂度:对数计算器
[1] 十大经典排序算法