1. 快速排序
不稳定,时间复杂度:平均O(nlogn)、最坏O(
),最好O(nlogn);
空间复杂度:O(logn)
缺点: 对小规模的数据集性能不是很好。
通过一趟sort将要排序的data分割成独立的两部分,其中一部分的所有数据比另一部分的所有数据都要小,然后再递归地对这两部分数据进行快排,直到整个待排序列有序。
对待排序列A[0],A[1], ..., A[N-1],选取序列的第一个元素(可以是任意元素)作为基准点,然后将所有比它小的数都放到它前面,所有比它大的元素放到它后面,这个过程称为一趟快速排序。每一趟快排都是将这一趟的基准数归位,直到所有的数都归位为止。
1.1 最简实现
未改变原列表
def quick_sort(arr):
if arr is None or len(arr) < 2:
return arr
return quick_sort([i for i in arr[1:] if i < arr[0]]) \
+ arr[0:1] \
+ quick_sort([i for i in arr[1:] if i >= arr[0]])
1.2 一般实现
def quick_sort2(arr):
if arr is None or len(arr) < 2:
return arr
left, right = [], []
base = arr[0]
arr.remove(base) # 移除基准点
for x in arr:
if x < base:
left.append(x)
else:
right.append(x)
return quick_sort2(left) + [base] + quick_sort2(right)
1.3 指针实现
在原列表上进行排序
def quick_sort3(arr, low, high):
if low >= high:
return
mid = getMid(arr, low, high)
quick_sort3(arr, low, mid-1)
quick_sort3(arr, mid+1, high)
def getMid(arr, low, high):
base = arr[low] # 选数组的首元素作为枢轴
while low < high:
# 比枢轴小的记录移动到低端
while low < high and arr[high] > base:
high -= 1
arr[low] = arr[high]
# 比枢轴大的记录移动到高端
while low < high and arr[low] < base:
low += 1
arr[high] = arr[low]
arr[low] = base
return low
1.4 测试
a = [4, 3, 9, -1, 7, 3]
quick_sort(a, 0, 5)
quick_sort3(a, 0, len(a)-1)
# [-1, 3, 3, 4, 7, 9]
2. 归并排序
1. 分解:将当前区间一分为二,即求分裂点mid;
2. 求解:递归地对两个子区间a[:mid]和a[mid:]进行归并排序(终结条件是子区间长度为1);
3. 合并:将已排序的两个子区间a[:mid]和a[mid:]归并为一个有序的区间a[:]。
稳定,时间复杂度:平均O(nlogn)、最坏O(nlogn),最好O(nlogn);
空间复杂度:O(n)
快速排序和归并排序都是分而治之,但归并排序是从中间直接将数列分成两个,而快排是比较后将小的放左边,大的放右边;合并时归并排序需要将两个数组重新再次排序,而快排则不需要,所有快排更高效一些。
注意:
while a 为True 等价于 a is not None and len(a)>0
2.1 简单实现
def merge_sort(arr):
if arr is None or len(arr) < 2:
return arr
mid = len(arr)//2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
result = []
while left and right:
result.append(left.pop(0) if left[0] <= right[0] else right.pop(0))
result.extend(left if left else right)
return result
2.2 一般实现
def merge_sort2(arr):
if arr is None or len(arr) < 2:
return arr
mid = len(arr)//2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(arr1, arr2):
result = []
i, j = 0, 0
while i < len(arr1) and j < len(arr2):
if arr1[i] <= arr2[j]:
result.append(arr1[i])
i += 1
else:
result.append(arr2[j])
j += 1
result.extend(arr1[i:])
result.extend(arr2[j:])
return result
2.3 测试
a = [4, 3, 9, -1, 7, 3]
merge_sort2(a)
# [-1, 3, 3, 4, 7, 9]
本文介绍两种重要的排序算法:快速排序和归并排序。快速排序是一种不稳定的排序算法,平均时间复杂度为O(nlogn),适用于大规模数据集。归并排序是一种稳定的排序算法,时间复杂度始终为O(nlogn),但空间复杂度较高。文章详细解释了这两种算法的实现原理及Python代码示例。
383





