面试/笔试时经常会问所知道的排序算法,并用2-3种排序算法码代码。
常见排序算法效率比较
排序方法 | 平均情况 | 最好情况 | 最坏情况 | 辅助空间 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O ( n 2 ) O(n^2) O(n2) | O ( n ) O(n) O(n) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 稳定 |
选择排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 不稳定 |
插入排序 | O ( n 2 ) O(n^2) O(n2) | O ( n ) O(n) O(n) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 稳定 |
希尔排序 | O ( n log n ) O(n \log n) O(nlogn)~ O ( n 2 ) O(n^2) O(n2) | O ( n 1.3 ) O(n^{1.3}) O(n1.3) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 不稳定 |
堆排序 | O ( n log n ) O(n \log n) O(nlogn) | O ( n log n ) O(n \log n) O(nlogn) | O ( n log n ) O(n \log n) O(nlogn) | O ( 1 ) O(1) O(1) | 不稳定 |
归并排序 | O ( n log n ) O(n \log n) O(nlogn) | O ( n log n ) O(n \log n) O(nlogn) | O ( n log n ) O(n \log n) O(nlogn) | O ( n ) O(n) O(n) | 稳定 |
快速排序 | O ( n log n ) O(n \log n) O(nlogn) | O ( n log n ) O(n \log n) O(nlogn) | O ( n 2 ) O(n^2) O(n2) | O ( log n ) O(\log n) O(logn)~ O ( n ) O(n) O(n) | 不稳定 |
快速排序
主要思想:分而治之 + 递归
选取数组第一个元素(或者中间/最后一个元素)作为基准值,数组根据基准值大小分为左右两部分,再递归,输出结果。
代码:
# 快速排序:分而治之 + 递归
def quick_sort(data):
"""快速排序"""
if len(data) >= 2: # 递归入口及出口
basic = data[0] # 选取列表第一个数为基准值
left, right = [], [] # 定义基准值左右两侧的列表
data.remove(basic) # 从原始数组中移除基准值
for num in data:
if num >= basic:
right.append(num) # 大于基准值的放到右边
else:
left.append(num) # 小于于基准值的放到左边
return quick_sort(left) + [basic] + quick_sort(right) # 递归
else:
return data
if __name__=="__main__":
nums = [49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22]
print(quick_sort(nums))