快速排序
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。 快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。 快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:
快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
1. 算法步骤
- 从数列中挑出一个元素,称为 “基准”(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
2. 动图演示

3. JavaScript 代码实现
1. function quickSort(arr, left, right) {2. var len = arr.length,3. partitionIndex,4. left = typeof left != 'number' ? 0 : left,5. right = typeof right != 'number' ? len - 1 : right;6. 7. if (left < right) {8. partitionIndex = partition(arr, left, right);9. quickSort(arr, left, partitionIndex-1);10. quickSort(arr, partitionIndex+1, right);11. }12. return arr;13. }14. 15. function partition(arr, left ,right) { // 分区操作16. var pivot = left, // 设定基准值(pivot)17. index = pivot + 1;18. for (var i = index; i <= right; i++) {19. if (arr[i] < arr[pivot]) {20. swap(arr, i, index);21. index++;22. }23. }24. swap(arr, pivot, index - 1);25. return index-1;26. }27. 28. function swap(arr, i, j) {29. var temp = arr[i];30. arr[i] = arr[j];31. arr[j] = temp;32. }33. function partition2(arr, low, high) {34. let pivot = arr[low];35. while (low < high) {36. while (low < high && arr[high] > pivot) {37. --high;38. }39. arr[low] = arr[high];40. while (low < high && arr[low] <= pivot) {41. ++low;42. }43. arr[high] = arr[low];44. }45. arr[low] = pivot;46. return low;47. }48. 49. function quickSort2(arr, low, high) {50. if (low < high) {51. let pivot = partition2(arr, low, high);52. quickSort2(arr, low, pivot - 1);53. quickSort2(arr, pivot + 1, high);54. }55. return arr;56. }
4. Python 代码实现
1. def quickSort(arr, left=None, right=None):2. left = 0 if not isinstance(left,(int, float)) else left3. right = len(arr)-1 if not isinstance(right,(int, float)) else right4. if left < right:5. partitionIndex = partition(arr, left, right)6. quickSort(arr, left, partitionIndex-1)7. quickSort(arr, partitionIndex+1, right)8. return arr9. 10. def partition(arr, left, right):11. pivot = left12. index = pivot+113. i = index14. while i <= right:15. if arr[i] < arr[pivot]:16. swap(arr, i, index)17. index+=118. i+=119. swap(arr,pivot,index-1)20. return index-121. 22. def swap(arr, i, j):23. arr[i], arr[j] = arr[j], arr[i]
5. Go 代码实现
1. func quickSort(arr []int) []int {2. return _quickSort(arr, 0, len(arr)-1)3. }4. 5. func _quickSort(arr []int, left, right int) []int {6. if left < right {7. partitionIndex := partition(arr, left, right)8. _quickSort(arr, left, partitionIndex-1)9. _quickSort(arr, partitionIndex+1, right)10. }11. return arr12. }13. 14. func partition(arr []int, left, right int) int {15. pivot := left16. index := pivot + 117. 18. for i := index; i <= right; i++ {19. if arr[i] < arr[pivot] {20. swap(arr, i, index)21. index += 122. }23. }24. swap(arr, pivot, index-1)25. return index - 126. }27. 28. func swap(arr []int, i, j int) {29. arr[i], arr[j] = arr[j], arr[i]30. }
6. C++版
1. //严蔚敏《数据结构》标准分割函数2. Paritition1(int A[], int low, int high) {3. int pivot = A[low];4. while (low < high) {5. while (low < high && A[high] >= pivot) {6. --high;7. }8. A[low] = A[high];9. while (low < high && A[low] <= pivot) {10. ++low;11. }12. A[high] = A[low];13. }14. A[low] = pivot;15. return low;16. }17. 18. void QuickSort(int A[], int low, int high) //快排母函数19. {20. if (low < high) {21. int pivot = Paritition1(A, low, high);22. QuickSort(A, low, pivot - 1);23. QuickSort(A, pivot + 1, high);24. }25. }
7. Java 代码实现
1. public class QuickSort implements IArraySort {2. 3. @Override4. public int[] sort(int[] sourceArray) throws Exception {5. // 对 arr 进行拷贝,不改变参数内容6. int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);7. 8. return quickSort(arr, 0, arr.length - 1);9. }10. 11. private int[] quickSort(int[] arr, int left, int right) {12. if (left < right) {13. int partitionIndex = partition(arr, left, right);14. quickSort(arr, left, partitionIndex - 1);15. quickSort(arr, partitionIndex + 1, right);16. }17. return arr;18. }19. 20. private int partition(int[] arr, int left, int right) {21. // 设定基准值(pivot)22. int pivot = left;23. int index = pivot + 1;24. for (int i = index; i <= right; i++) {25. if (arr[i] < arr[pivot]) {26. swap(arr, i, index);27. index++;28. }29. }30. swap(arr, pivot, index - 1);31. return index - 1;32. }33. 34. private void swap(int[] arr, int i, int j) {35. int temp = arr[i];36. arr[i] = arr[j];37. arr[j] = temp;38. }39. 40. }
8. PHP 代码实现
1. function quickSort($arr)2. {3. if (count($arr) <= 1)4. return $arr;5. $middle = $arr[0];6. $leftArray = array();7. $rightArray = array();8. 9. for ($i = 1; $i < count($arr); $i++) {10. if ($arr[$i] > $middle)11. $rightArray[] = $arr[$i];12. else13. $leftArray[] = $arr[$i];14. }15. $leftArray = quickSort($leftArray);16. $leftArray[] = $middle;17. 18. $rightArray = quickSort($rightArray);19. return array_merge($leftArray, $rightArray);20. }
整理人:豆包AI助手
