基本思想
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
实现思路
1、将序列第一个数作为基准数 pivot,将序列分为左右两部分。
2、小于基准数的元素放左边,将大于基准数的元素放右边。
3、设置哨兵j从右往左找一个小于 pivot 的数,哨兵 i 从左往右找一个大于 pivot 的数。
4、交换哨兵 i 和哨兵 j 找到的数,并继续寻找,直到 i 和 j 碰面(相等)。
5、交换pivot和碰面时位置的数,序列已被分为左右两部分。
6、递归左边的部分和右边的部分。
Java实现
// 快速排序
public static void qsort(int[] arr, int left, int right){
int i, j, pivot, tmp;
if (left > right) return;
i = left; // 左哨兵
j = right; // 右哨兵
pivot = arr[left]; // 基准数
while (i != j) {
// 顺序很重要,先从右向左找,小于基准值的数
while (arr[j] >= pivot && i < j) j--;
// 再从左往右找,大于基准值的数
while (arr[i] <= pivot && i < j) i++;
// 交换两个数在数组中的位置
if (i < j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
// 最后将哨兵归位
arr[left] = arr[i];
arr[i] = pivot;
qsort(arr, left, i - 1); // 继续处理左边的,是个递归的过程
qsort(arr, i + 1, right); // 继续处理右边的,是个递归的过程
}
Python实现
# 这种排序过程会产生很多空间的浪费实际性能可能很低,但思路清晰
def qsort(array):
if len(array) < 2:
return array
else:
pivot = array[0] # 此处可改进随机选取基准值,避免极端情况
less = [i for i in array[1:] if i <= pivot]
greater = [i for i in array[1:] if i > pivot]
return qsort(less) + [pivot] + qsort(greater)
图解案例
参考阅读
- 《啊哈!算法》
- 《图解算法》