侏儒排序法
def gnome_sort(seq):
i = 0
while i < len(seq):
if i == 0 or seq[i-1] <= seq[i]:
i += 1
else:
seq[i], seq[i-1] = seq[i-1], seq[i]
i -= 1
归并排序法
一个对于任何值都可用的算法,最坏情况下至少需要消耗Ω(nlgn)
的时间。
def merge_sort(seq):
mid = len(seq) // 2
lft, rgt = seq[:mid], seq[mid:]
if len(lft) > 1:
lft = merge_sort(lft)
if len(rgt) > 1:
rgt = merge_sort(rgt)
res = []
while lft and rgt:
if lft[-1] >= rgt[-1]:
res.append(lft.pop())
else:
res.append(rgt.pop())
res.reverse()
return (lft or rgt) + res
# 测试用例
seq = [2, 7, 1, 4, 3]
# seq lft rgt res
# [2, 7] [2] [] [7]
# [4, 3] [] [3] [4]
# [1, 4, 3] [1] [] [3, 4]
# [2, 7, 1, 4, 3] [] [1] [2, 3, 4, 7]
直接插入排序
def insert_sort(seq):
for i in range(1, len(seq)):
j = i
while j > 0 and seq[j-1] > seq[j]:
seq[j-1], seq[j] = seq[j], seq[j-1]
j -= 1
简单选择排序
def select_sort(seq):
for i in range(len(seq)):
idx = i
for j in range(i+1, len(seq)):
if seq[idx] > seq[j]:
idx = j
seq[idx], seq[i] = seq[i], seq[idx]
return seq
seq = [10, 31, 8, 19, 9, 23]
print(select_sort(seq)) # [8, 9, 10, 19, 23, 31]
计数排序
计数法要求所操作的问题元素是可以被哈希的。
from collections import defaultdict
def counting_sort(seq, key=lambda x: x):
res, counts = [], defaultdict(list)
for su in seq:
counts[key(su)].append(su)
for nu in range(min(counts), max(counts)+1):
res.extend(counts[nu])
return res
这里的键值函数必须被限制在一定范围内,如果其取值范围为0~k-1
,那么该算法的运行时间就应为θ(n+k)
。
另外,如果其中有若干个值的键相等的话,那么它们之间最终将保持原有的顺序,有这样属性的排序算法被称为稳定的。
快速排序
def quick_sort(seq):
if len(seq) < 2:
return seq
else:
pivot = seq[0]
less = [su for su in seq[1:] if su <= pivot]
greater = [su for su in seq[1:] if su > pivot]
return quick_sort(less) + [pivot] + quick_sort(greater)
seq = [10, 31, 8, 19, 9, 23]
print(quick_sort(seq)) # [8, 9, 10, 19, 23, 31]
递归只是让解决方案更清晰,并没有性能上的优势。
def quick_sort(seq, low, high):
if low < high:
pivot = partition(seq, low, high)
quick_sort(seq, low, pivot-1)
quick_sort(seq, pivot+1, high)
def partition(seq, low, high):
pivot = seq[low]
while low < high:
while low < high and seq[high] >= pivot:
high -= 1
seq[low] = seq[high]
while low < high and seq[low] <= pivot:
low += 1
seq[high] = seq[low]
seq[low] = pivot
return low
seq = [10, 31, 8, 19, 9, 23]
quick_sort(seq, 0, len(seq)-1)
print(seq)
(最近更新:2019年08月28日)