简介

快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。

算法步骤

  1. 从数列中挑出一个元素,称为 “基准“(pivot);
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

快速排序 - 图1

代码实现

  1. public class QuickSort {
  2. public int[] sort(int[] sourceArray) throws Exception {
  3. // 对 arr 进行拷贝,不改变参数内容
  4. int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
  5. return quickSort(arr, 0, arr.length - 1);
  6. }
  7. private int[] quickSort(int[] arr, int left, int right) {
  8. if (left < right) {
  9. int partitionIndex = partition(arr, left, right);
  10. quickSort(arr, left, partitionIndex - 1);
  11. quickSort(arr, partitionIndex + 1, right);
  12. }
  13. return arr;
  14. }
  15. private int partition(int[] arr, int left, int right) {
  16. // 设定基准值(pivot)
  17. int pivot = left;
  18. int index = pivot + 1;
  19. for (int i = index; i <= right; i++) {
  20. if (arr[i] < arr[pivot]) {
  21. swap(arr, i, index);
  22. index++;
  23. }
  24. }
  25. swap(arr, pivot, index - 1);
  26. return index - 1;
  27. }
  28. private void swap(int[] arr, int i, int j) {
  29. int temp = arr[i];
  30. arr[i] = arr[j];
  31. arr[j] = temp;
  32. }
  33. }