1.动画展示

快速.gif

2.思路分析

快速排序(Quicksort)是对冒泡排序的一种改进。 基本思想是:通过- - 趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排
序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

image.png

image.png

3.复杂度分析

1.时间复杂度:

最坏情况就是每一次取到的元素就是数组中最小/最大的,这种情况其实就是冒泡排序了(每一次都排好一个元素的顺序)
这种情况时间复杂度就好计算了,就是冒泡排序的时间复杂度:T[n] = n (n-1) = n^2 + n;
最好情况下是O(nlog2n),推导过程如下:
递归算法的时间复杂度公式:T[n] = aT[n/b] + f(n)
4.快速排序 - 图4
所以*平均时间复杂度为O(nlog2n)

2. 空间复杂度:

快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据:
最优的情况下空间复杂度为:O(log2n);每一次都平分数组的情况
最差的情况下空间复杂度为:O( n );退化为冒泡排序的情况
所以平均空间复杂度为O(log2n)

4.代码实现

代码1,较容易理解,设置基准为首元素

  1. public static void quick(int[] arr, int low, int high) {
  2. int pivot = arr[low];
  3. int i = low;
  4. int j = high;
  5. while (i < j) {
  6. while ((i < j) && arr[i] < pivot) {
  7. i++;
  8. }
  9. while ((i < j) && arr[j] > pivot) {
  10. j--;
  11. }
  12. if (arr[i] == arr[j] && (i < j)) {
  13. //有重复元素的情况
  14. i++;
  15. } else {
  16. //不是相同元素,交换两个值
  17. swap(arr, i, j);
  18. }
  19. }
  20. if (low < (i - 1)) {
  21. quick(arr, low, i - 1);
  22. }
  23. if ((j + 1) < high) {
  24. quick(arr, j + 1, high);
  25. }
  26. }
  1. public class QuickSort {
  2. public static void main(String[] args) {
  3. int[] arr = {-9,78,0,23,-567,70, -1,900, 4561};
  4. System.out.println(Arrays.toString(arr));
  5. System.out.println("-----快速排序-----");
  6. quickSort(arr,0,arr.length-1);
  7. System.out.println(Arrays.toString(arr));
  8. }
  9. public static void quickSort(int[] arr,int left, int right) {
  10. int l = left; //左下标
  11. int r = right; //右下标
  12. //pivot 中轴值
  13. int pivot = arr[(left + right) / 2];
  14. int temp = 0; //临时变量,作为交换时使用
  15. //while循环的目的是让比pivot 值小放到左边
  16. //比pivot 值大放到右边
  17. while( l < r) {
  18. //在pivot的左边一直找,找到大于等于pivot值,才退出
  19. while( arr[l] < pivot) {
  20. l += 1;
  21. }
  22. //在pivot的右边一直找,找到小于等于pivot值,才退出
  23. while(arr[r] > pivot) {
  24. r -= 1;
  25. }
  26. //如果l >= r说明pivot 的左右两的值,已经按照左边全部是
  27. //小于等于pivot值,右边全部是大于等于pivot值
  28. if( l >= r) {
  29. break;
  30. }
  31. //交换中轴左右的值
  32. temp = arr[l];
  33. arr[l] = arr[r];
  34. arr[r] = temp;
  35. //如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
  36. if(arr[l] == pivot) {
  37. r -= 1;
  38. }
  39. //如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
  40. if(arr[r] == pivot) {
  41. l += 1;
  42. }
  43. }
  44. // 如果 l == r, 必须l++, r--, 否则为出现栈溢出
  45. if (l == r) {
  46. l += 1;
  47. r -= 1;
  48. }
  49. //向左递归
  50. if(left < r) {
  51. quickSort(arr, left, r);
  52. }
  53. //向右递归
  54. if(right > l) {
  55. quickSort(arr, l, right);
  56. }
  57. }
  58. }

运行截图
image.png