返回
手撕十大排序算法(二)之快排篇
闲谈
2023-10-30 00:10:54
快速排序的思维导图
+--------+
| 快速排序 |
+--------+
/ \
/ \
+-------------+ +---------------+
| 分治策略 | | 哨兵划分 |
+-------------+ +---------------+
/ \ / \
/ \ / \
+----------+ +----------+ +-----------+ +-----------+
| 原地划分 | | 递归划分 | | 原地排序 | | 递归排序 |
+----------+ +----------+ +-----------+ +-----------+
快速排序的算法步骤
- 选取哨兵 :在待排序序列中选取一个元素作为哨兵,通常是序列的第一个或最后一个元素。
- 原地划分 :以哨兵为基准,将序列划分为两个子序列:
- 小于哨兵的部分 :包含所有小于哨兵的元素。
- 大于哨兵的部分 :包含所有大于哨兵的元素。
- 递归划分 :对两个子序列分别进行快速排序,直至每个子序列只有一个元素或为空。
- 原地排序 :将两个有序子序列合并,得到一个有序序列。
快速排序的代码实现(Python)
def quick_sort(arr):
"""
快速排序算法实现
:param arr: 待排序列表
:return: 排序后的列表
"""
# 递归出口:列表为空或只有一个元素
if len(arr) <= 1:
return arr
# 选择哨兵
pivot = arr[0]
# 原地划分
left = []
right = []
for i in range(1, len(arr)):
if arr[i] < pivot:
left.append(arr[i])
else:
right.append(arr[i])
# 递归划分
left = quick_sort(left)
right = quick_sort(right)
# 原地排序
return left + [pivot] + right
快速排序的时间复杂度分析
快速排序的时间复杂度为O(nlogn),在以下两种情况下达到最优时间复杂度:
- 最好情况 :序列是已经排好序的或接近有序的,此时快速排序的时间复杂度为O(nlogn)。
- 平均情况 :序列是随机的,此时快速排序的时间复杂度也为O(nlogn)。
快速排序的空间复杂度分析
快速排序的空间复杂度为O(logn),因为递归调用的栈空间随着序列的不断划分而不断增加,最坏情况下递归调用的栈空间为O(logn)。
快速排序的优缺点总结
优点 :
- 快速排序是一种高效的排序算法,时间复杂度为O(nlogn)。
- 快速排序是一种原地排序算法,不需要额外的空间。
- 快速排序是一种稳定的排序算法,即对于相同的元素,在排序后它们保持相对顺序不变。
缺点 :
- 快速排序是一种不稳定的排序算法,即对于相同的元素,在排序后它们可能改变相对顺序。
- 快速排序的性能依赖于哨兵的选择,如果哨兵选择不当,则可能会导致最坏情况的时间复杂度为O(n^2)。
结语
快速排序作为十大经典排序算法之一,以其高效的性能和广泛的适用性,在实践中发挥着重要的作用。掌握快速排序的原理和实现,对于程序员来说是必备的基本功。下篇,我们将继续深入剖析另外一种经典排序算法——桶排序。