当前位置:   article > 正文

Java 七大排序之快速排序(三种方法包含优化方法)_java快速排序

java快速排序

(1)基本思想

任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

(2)代码实现

1)  挖坑法

划分完之后,再左右递归。当遇到array[right] >= tmp ,交换 array[left] 和 array[right] ;

 以此类推,最终得到正确排序。 

  1. public static int partition(int[] array,int left,int right){
  2. int tmp =array[left];
  3. while (left < right) {
  4. while (left < right && array[right] >= tmp){
  5. right--;
  6. }
  7. array[left] = array[right];
  8. while (left < right && array[left] <= tmp){
  9. left++;
  10. }
  11. array[right] = array[left];
  12. }
  13. array[left] = tmp;
  14. return left;
  15. }
  16. public static void quickSort(int[] array) {
  17. quick(array,0,array.length-1);
  18. }
  19. public static void quick(int[] array,int start,int end) {
  20. if (start >= end) {
  21. return;
  22. }
  23. //先划分,再左右递归
  24. int pivot = partition(array,start,end);
  25. quick(array,start,pivot-1);
  26. quick(array,pivot+1,end);
  27. }

2)Hoare法

当 right 找到比基准小的 ,left 找到比基准大的时 交换它们的值。

  1. public static int partition2(int[] array,int left,int right){
  2. int tmp =array[left];
  3. int i = left;
  4. while (left < right) {
  5. while (left < right && array[right] >= tmp){
  6. right--;
  7. }
  8. while (left < right && array[left] <= tmp){
  9. left++;
  10. }
  11. swap(array,left,right);
  12. }
  13. //相遇之后
  14. swap(array,left,i);
  15. return left;
  16. }

swap 方法为交换方法,在我前面的文章中写过,这里就不写了,有需要的可以翻一下上一篇文章。

3)前后指针法(了解即可)

写法1:

  1. private static int partition(int[] array, int left, int right) {
  2. int prev = left ;
  3. int cur = left+1;
  4. while (cur <= right) {
  5. if(array[cur] < array[left] && array[++prev] != array[cur]) {
  6. swap(array,cur,prev);
  7. }
  8. cur++;
  9. }
  10. swap(array,prev,left);
  11. return prev;
  12. }

写法2:

  1. private static int partition(int[] array, int left, int right) {
  2. int d = left + 1;
  3. int pivot = array[left];
  4. for (int i = left + 1; i <= right; i++) {
  5. if (array[i] < pivot) {
  6. swap(array, i, d);
  7. d++;
  8. }
  9. }
  10. swap(array, d - 1, left);
  11. return d - 1;
  12. }

4)非递归实现快速排序

  1. public static void quickSort(int[] array) {
  2. Deque<Integer> stack = new LinkedList<>();
  3. int left = 0;
  4. int right = array.length-1;
  5. int pivot = partition(array,left,right);
  6. if (pivot > left+1) {
  7. stack.push(left);
  8. stack.push(pivot-1);
  9. }
  10. if (pivot < right-1) {
  11. stack.push(pivot+1);
  12. stack.push(right);
  13. }
  14. while (!stack.isEmpty()) {
  15. right = stack.pop();
  16. left = stack.pop();
  17. pivot = partition(array,left,right);
  18. if (pivot > left+1) {
  19. stack.push(left);
  20. stack.push(pivot-1);
  21. }
  22. if (pivot < right-1) {
  23. stack.push(pivot+1);
  24. stack.push(right);
  25. }
  26. }
  27. }

(3)特性总结

1. 快速排序整体的综合性能和使用场景都是比较好;

2. 时间复杂度:O(N*logN) 空间复杂度:O(logN);

3.稳定性:不稳定。

(4)快速排序的优化

当需要排序的元素太多,我们这时选取基准就非常重要了,因此我们采取三数取中法来选取合适的基准。

三数取中法:在三个数当中选出既不是最大的也不是最小的。

  1. private static int midTree(int[] array,int left,int right) {
  2. int mid = (left+right)/2;
  3. if (array[left] < array[right]) {
  4. if (array[mid] < array[left]) {
  5. return left;
  6. } else if(array[mid] > array[right]) {
  7. return right;
  8. } else {
  9. return mid;
  10. }
  11. } else {
  12. if (array[mid] < array[right]) {
  13. return right;
  14. } else if(array[mid] > array[left]) {
  15. return left;
  16. } else {
  17. return mid;
  18. }
  19. }
  20. }

如果遇到什么问题欢迎在评论区补充哦!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/88832
推荐阅读
相关标签
  

闽ICP备14008679号