ps:快排会有边界问题,所以背一个模板

  1. static void QuickSort(int[] q,int l,int r) {
  2. if(l >= r) {
  3. return;
  4. }
  5. int i = l-1;
  6. int j = r+1;
  7. int medium = nums[l];
  8. while (i<j) {
  9. do i++; while (q[i]<medium); !!这里是易忘点
  10. do j--; while (q[j]>medium);
  11. if (i < j) {
  12. int temp = q[i];
  13. q[i] = q[j];
  14. q[j] = temp;
  15. }
  16. }
  17. //递归排序左边
  18. QuickSort(q, l, j);
  19. //递归排序右边
  20. QuickSort(q, j + 1, r);
  21. }

应用层面剖析
方法形参传值都传边界,创建指针时向外拓一位(也就是左边界-1,右边界+1)方便进行判断
判断的值是 取当前数组的左边界

条件判断
只有指针穿过,或相等,整个数组才是被指针划分开左右两个理想区域(理想区域就是左边都比比较值小,右边都比比较值大)
如果他们卡在了两边的不同点
为什么卡住?
我们先分析一下为什么会卡住,因为指针发现了目标,把指针想象成两个过滤网,有过滤不掉的东西,它就会卡住不走。左指针是因为碰到大的(因为它的任务是将左区域过滤成小的),右指针是因为碰到小的(因为它的任务是把右区域过滤成大的),这个大和小是相对于比较值而言。
卡住了怎么办?
既然左右两个过滤网都碰到了不属于自己的东西,那就互相交换咯(if判断就是来做这个事的)
递归区域划分
右指针最后指到哪,那个地方以及前面整个都是左区域(因为J停的地方就是小的它才会停,如果比比较值大的话它就不会停那了),我们比较值都用了数组左边界,所以 其实它就是不断在排序右区域
注意
中间值不能用右边界,会出现溢出问题,用左边界稳妥。


个人整理

判断

递归总有一个结束判断,当左边界>=有边界,证明数组为空,结束返回

构造指针和中间值

指针往外拓一位(方便移动的时候判断)
比较值为数组左边界索引值(防止溢出)

移动过滤(直到两指针交汇才算这一轮过滤成功)

左指针就是左滤网,它专筛比“比较值”小的值 注:用比较值和指针指向的数组值进行比较
右指针则相反,它专筛比“比较值”大的值
筛完以后如果左指针小于右指针,说明他们遇到茬了,马上交换数组的这两个值。注:交换完了还要再循环,确保交换完以后彻底筛干净

左右区域递归

递归调用方法,分别调用左边界到右指针的,和右指针右边的。

番外

在这个排序思想中,两个指针相等或者越过都是理想情况,因为只有他们两个过滤网都成功过滤了,才会相等或传过。所以如果左指针<=右指针,就是两个过滤网都遇到茬了,交换。简单记忆:判断,构造,移动,递归
ps:今天有点心得,发现c++的指针其实可以用参数来代替,指针就是索引

代码

  1. package com.company;
  2. import java.util.Scanner;
  3. public class QuickSortRepeat {
  4. static void QuickSort(int[] nums,int l,int r){
  5. /*判断*/
  6. if(l>=r){
  7. return;
  8. }
  9. /*构造指针和比较值*/
  10. int i = l-1;
  11. int j = r+1;
  12. int x = nums[l];
  13. /*移动指针并判断*/
  14. while (i<j){
  15. do{ i++;}while(nums[i]<x);
  16. do{ j--;}while(nums[j]>x);
  17. if (i<j){
  18. int temp = nums[i];
  19. nums[i] = nums[j];
  20. nums[j] = temp;
  21. }
  22. }
  23. /*左右区域递归*/
  24. QuickSort(nums,l,j);
  25. QuickSort(nums,j+1,r);
  26. }
  27. public static void main(String[] args) {
  28. /*外界输入*/
  29. Scanner sc = new Scanner(System.in);
  30. int ListSize = sc.nextInt();
  31. int[] nums = new int[ListSize];
  32. String[] strs = sc.next().trim().split(",");
  33. for (int i=0;i<ListSize;i++){
  34. nums[i] = Integer.parseInt(strs[i]);
  35. }
  36. /*调用方法*/
  37. QuickSort(nums,0,nums.length-1);
  38. /*查询*/
  39. for (int i:nums) {
  40. System.out.print(i+",");
  41. }
  42. }
  43. }