快速排序的原理

1-1 快速排序法的原理【一手微信itit11223344】.mp4_20211016_185320975.jpg

partion原理图示
快速排序 - 图2

partion图示过程(这里 p 的位置默认是 0)

快速排序 - 图3

快速排序第一版

  1. public static <E extends Comparable<E>> void sort(E[] arr){
  2. //这个地方注意位置是arr.length-1
  3. sort(arr,0, arr.length-1);
  4. }
  5. private static <E extends Comparable<E>> void sort(E[] arr,int l,int r){
  6. if (l >= r) return;
  7. int p = partition(arr,l,r);
  8. sort(arr,l,p-1);
  9. sort(arr,p+1,r);
  10. }
  11. private static <E extends Comparable<E>> int partition(E[] arr,int l , int r){
  12. //生成[l,r]之间的随机索引
  13. int p = l + (new Random()).nextInt(r-l+1);
  14. swap(arr,l,p);
  15. //arr[l+1,j] < v ; arr[j+1,i-1] > v
  16. int j = l;
  17. for (int i = j+1; i <= r ; i++) {
  18. if (arr[i].compareTo(arr[l]) < 0){
  19. j++;
  20. swap(arr,i,j);
  21. }
  22. }
  23. //最后将第一个元素v,插入到<v和>v的位置中间
  24. swap(arr,l,j);
  25. return j;
  26. }
  • 详细快速排序的过程:

第一版中的一系列问题

  • 在完全有序的数组中,使用快速排序会栈溢出
    • 解决方案:为快速排序添加随机化
  • 如果数组中的值全部相等,排序效率会大打折扣
    • 解决方案:重新设计partition函数(双路快速排序)

双路快速排序

  • 引入原因:如果数组全部都有序,快速排序会退化成为一个O(n)的算法
  • 原理:从两端出击,一直向中间挪
  • 原理图示

快速排序 - 图4

三路快速排序算法

  • 引入原因一样
  • 原理图示

2-5 三路快速排序法【一手微信itit11223344】.mp4_20211018_144736901.jpg

快速排序 - 图6

  • 过程图示:

快速排序 - 图7

复杂度分析

作业

  • 作业一:只new一次Random
  • 作业二:不使用随机化来作为标定点,而直接取一半 swap(arr,l,(l+r)/2)。因此为ArrayGenerator添加一个方法,generateSpecialArray来为partition生成一个O(n2)级别的数组
  • 作业3 : leetcode75、215、剑指Offer 40、面试题17.14