【经典算法】快速排序

比眉伴天荒 2023-09-30 18:44 59阅读 0赞

快速排序(Quicksort),计算机科学词汇,适用领域Pascal,c++等语言,是对冒泡排序算法的一种改进。


一、基本原理:

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

  1. 从数列中挑出一个元素,称为 “基准”(pivot);

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

  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

997a327bd9fd52d305e18dbaf12bca55.png

循环之后得到了基准值左右两边的序列了,交换的是起始和结束位置的值,不是基准值。

二、一趟快速排序算法描述:

48765001e062fbfaaf7db85c38a6bb60.png

三、时间复杂度分析:

经过上述一趟快速排序,我们只确定了一个元素的最终位置,我们最终需要经过n趟快速排序才能将一个含有 n 个数据元素的序列排好序,下面我们来分析其时间复杂度.

f6294e2d6c4ab0338f4d944719cd8e58.png

1、最好时间复杂度:

核心点:最好情况下,每一次划分都正好将数组分成长度相等的两半

c66302d211e30adf5340485dbbe6c459.png

2、最坏时间复杂度:

核心点:最坏情况下,每一次划分都将数组分成了0和n-1两部分

ebce7f9fe4bb33cfa1e9d66116af2211.png

3、平均时间复杂度:

核心点:任意一种划分情况出现的概率都相等

代码实现:

  1. package com.example.demo;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Arrays;
  4. import java.util.Date;
  5. /**
  6. * @author Biyu
  7. * @projectName demo
  8. * @className: QuickSort
  9. * @date: 2023-01-12 23:21
  10. */
  11. public class QuickSort {
  12. public static void main(String[] args) {
  13. int[] arr = {13, 21, 6, 18, 14, 2, 30, 45};
  14. System.out.print("排序前:");
  15. System.out.println(Arrays.toString(arr));
  16. Date beginDate = new Date();
  17. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  18. String beginDateStr = simpleDateFormat.format(beginDate);
  19. System.out.println("排序前的时间是:" + beginDateStr);
  20. quickSort(arr, 0, arr.length - 1);
  21. System.out.print("排序后:");
  22. System.out.println(Arrays.toString(arr));
  23. Date endDate = new Date();
  24. String endDateStr = simpleDateFormat.format(endDate);
  25. System.out.println("排序后的时间是:" + endDateStr);
  26. }
  27. public static void quickSort(int[] arr, int left, int right) {
  28. int l = left; //左下标
  29. int r = right; //右下标
  30. //pivot 基准值
  31. int pivot = arr[(left + right) / 2];
  32. int temp = 0; //临时变量,作为交换时使用
  33. // while循环的目的是让:
  34. // 比pivot 值小放到左边
  35. // 比pivot 值大放到右边
  36. while (l < r) {
  37. //在pivot的左边一直找,找到大于等于pivot值,才退出
  38. while (arr[l] < pivot) {
  39. l += 1;
  40. }
  41. //在pivot的右边一直找,找到小于等于pivot值,才退出
  42. while (arr[r] > pivot) {
  43. r -= 1;
  44. }
  45. //如果l >= r说明pivot 的左右两的值,已经按照左边全部是
  46. //小于等于pivot值,右边全部是大于等于pivot值
  47. if (l >= r) {
  48. break;
  49. }
  50. //交换
  51. temp = arr[l];
  52. arr[l] = arr[r];
  53. arr[r] = temp;
  54. //如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
  55. if (arr[l] == pivot) {
  56. r -= 1;
  57. }
  58. //如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
  59. if (arr[r] == pivot) {
  60. l += 1;
  61. }
  62. }
  63. // 如果 l == r, 必须l++, r--, 否则为出现栈溢出
  64. if (l == r) {
  65. l += 1;
  66. r -= 1;
  67. }
  68. //向左递归
  69. if (left < r) {
  70. quickSort(arr, left, r);
  71. }
  72. //向右递归
  73. if (right > l) {
  74. quickSort(arr, l, right);
  75. }
  76. }
  77. }
  • 运行结果:

1e2dfc713abceacc9a3e933c892f2d6b.png

发表评论

表情:
评论列表 (有 0 条评论,59人围观)

还没有评论,来说两句吧...

相关阅读

    相关 经典排序算法

    一、概念: 将杂乱无序的数据元素,通过一定的方法按关键字顺序排列的过程就是排序。 二、常见的排序算法: 不稳定的排序算法:快速排序、希尔排序、堆排序、直接选择排序

    相关 经典排序算法

    冒泡排序 冒泡排序(Bubble Sort),又被称为气泡排序或泡沫排序。 它是一种较简单的排序算法。它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次的比较相