一、快速排序法介绍

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

二、快速排序法示意图

排序算法-快速排序 - 图1
排序算法-快速排序 - 图2

三、快速排序法应用实例

需求:

对 [-9,78,0,23,-567,70] 进行从小到大的排序,要求使用快速排序法。

1.使用快速排序以中间值为基准值,代码实现

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

2.使用快速排序以第一个数为基准值,代码实现

  1. public class QuickSort {
  2. public static void main(String[] args) {
  3. int[] arr = {-9,78,0,23,-567,70, -1,900, 4561};
  4. quickSort(arr, 0, arr.length-1);
  5. }
  6. //快速排序算法(从小到大)
  7. //arr:需要排序的数组,left:需要排序的区间左边界,right:需要排序的区间的右边界
  8. public static void quickSort(int[] arr,int left, int right) {
  9. int temp = arr[left]; //将区间的第一个数作为基准数
  10. int l = left; //从左到右进行查找时的“指针”,指示当前左位置
  11. int r = right;//从右到左进行查找时的“指针”,指示当前右位置
  12. //不重复遍历
  13. while (l < r) {
  14. //当右边的数大于基准数时,略过,继续向左查找
  15. //不满足条件时跳出循环,此时的j对应的元素是小于基准元素的
  16. while (l < r && arr[r] > temp) { //(重复的基准元素集合到左区间)
  17. r--;
  18. }
  19. arr[l] = arr[r]; //将右边小于等于基准元素的数填入左边相应位置
  20. //当左边的数小于等于基准数时,略过,继续向右查找
  21. //不满足条件时跳出循环,此时的i对应的元素是大于等于基准元素的
  22. while (l < r && arr[l] <= temp) {
  23. l++;
  24. }
  25. arr[r] = arr[l];//将左边大于基准元素的数填入左边相应位置
  26. }
  27. // 将基准值填入
  28. // 因为基准值是从左边的第一个位置获取的,所以也是最后赋值到左边
  29. arr[l] = temp;
  30. //此时的i即为基准元素的位置
  31. //对基准元素的左边子区间进行相似的快速排序
  32. if (left < l - 1) { // 如果 left < l- 1 说明左边还没有遍历完
  33. quickSort2(arr, left, l - 1);
  34. }
  35. if (l + 1 < right) { // 如果 right > l + 1 说明右边还没有遍历完
  36. quickSort2(arr, l + 1, right);
  37. }
  38. }
  39. }