【每周一算】十大经典排序算法之快速排序

569 阅读1分钟

排序的时间复杂度

| 算法名称 | 平均时间复杂度 | 空间复杂度 |稳定性| | :---:| :----: | :----: ||:---:| | 快速排序 | O(nlogn) |O(logn) |不稳定|

快速排序过程

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

代码实现

public class QuickSortTest01 {


  public static void quicksort(int[] arr, int left, int right) {

    if (left >= right) {
      return;
    }

    int flag = left;
    int start = left;
    int end = right;

    while (left < right) {
      while ((left < right) && (arr[right] >= arr[flag])) {
        right--;
      }
      if (arr[right] < arr[flag]) {
        int tmp = arr[right];
        arr[right] = arr[flag];
        arr[flag] = tmp;
        flag = right;
      }

      while ((left < right) && (arr[left] <= arr[left])) {
        left++;
      }

      if (arr[left] > arr[flag]) {
        int tmp = arr[left];
        arr[left] = arr[flag];
        arr[flag] = tmp;
        flag = left;
      }
    }

    quicksort(arr, start, flag - 1);
    quicksort(arr, flag + 1, end);


  }


  /**
   * 占位法
   *
   * @param arr
   * @param left
   * @param right
   */
  public static void quick_sort(int[] arr, int left, int right) {
    if (left < right) {

      //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
      int i = left, j = right, x = arr[left];

      while (i < j) {
        while (i < j && arr[j] >= x) // 从右向左找第一个小于x的数
          j--;
        if (i < j) {
          arr[i++] = arr[j];
        }

        while (i < j && arr[i] < x) // 从左向右找第一个大于等于x的数
          i++;
        if (i < j) {
          arr[j--] = arr[i];
        }
      }
      arr[i] = x;
      quick_sort(arr, left, i - 1); // 递归调用
      quick_sort(arr, i + 1, right);
    }
  }

  public static void main(String[] args) {
    int[] arr = new int[] {23, 100, 10, 5, 2, 200};

    quick_sort(arr, 0, arr.length - 1);


    System.out.println(arr);
  }
}