1. 快速排序是交换排序的一种,也是对冒泡排序的一种改进,其基本思想是基于分治法的;
2. 快速排序算法的思想是:在待排序表L[1...n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1...k-1], L[k+1...n], 使得L[1...k-1]中所有元素小于pivot, L[k+1...n]中所有元素大于或等于pivot, 则pivot放在了其最终位置L(k)上,这个过程称作一趟快速排序。而后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或为空为止,即所有元素放在了其最终位置上。
3. 通常取待排序表中第一个元素作为枢轴值(基准)对表进行划分,即,必须将待排序表中比枢轴值大的元素向右移动,比枢轴值小的向左移动,使得一趟划分操作之后,表中的元素被枢轴值一分为二。
4. 快速排序的算法性能分析:
(4.1)空间效率:最坏情况为O(n),最好情况为,平均情况为O(log2n);
(4.2)时间复杂度:最坏情况下,时间复杂度为O(n2),平均时间复杂度O(nlog2n);
(4.3)稳定性:不稳定的排序方法;
(4.4)在快速排序算法中,并不产生有序子序列,但每一趟排序后将一个元素(基准元素)放到其最终位置上。
5. 代码
(5.1)交换法
package myleetcode; import java.util.Arrays; /** * @author sunhongguang * @create 2021-03-26-17:29 */ public class QuickSort { public static void main(String[] args) { int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19}; quickSort(arr, 0, arr.length-1); System.out.println(Arrays.toString(arr)); } /** * * @param arr 待排序数组 * @param low 待排序数组左边索引 * @param high 待排序数组右边索引 */ public static void quickSort(int[] arr,int low,int high){ int i,j,temp,t; if(low > high){ return; } i = low; // 左边哨兵的索引 j = high; // 右边哨兵的索引 temp = arr[low]; //temp是基准位,以最左边为基准位 while(i<j){ // 从右往左找比基准位小的数 while(temp <= arr[j] && i<j){ j--; } while(temp >= arr[i] && i<j){ i++; } if(i<j){ t = arr[i]; arr[i] = arr[j]; arr[j] = t; } } // 将基准位与i==j位置处的元素进行交换 arr[low] = arr[i]; arr[i] = temp; //递归调用,快速排序左边部分 quickSort(arr, low, j-1); //递归调用,快速排序右边部分 quickSort(arr, j+1, high); } }
结果:
(5.2) 填坑法(版本1)
1 // 快速排序-填坑法(版本1) 2 public static void quickSort_v2(int[] arr, int low, int high) { 3 if (low < high) { 4 int i = low; 5 int j = high; 6 int temp = arr[low]; 7 while (i < j) { 8 while (i < j && temp <= arr[j]) { 9 j--; 10 } 11 if (i < j) { 12 arr[i] = arr[j]; 13 i++; 14 } 15 while (i < j && temp >= arr[i]) { 16 i++; 17 } 18 if (i < j) { 19 arr[j] = arr[i]; 20 j--; 21 } 22 } 23 arr[i] = temp; 24 quickSort_v2(arr, low, i - 1); 25 quickSort_v2(arr, i + 1, high); 26 } 27 }
(5.3)填坑法(版本2)
1 /** 2 * 快速排序-填坑法v2 3 * 4 * @param arr 5 * 待排序数组 6 * @param low 7 * 递归排序过程中的起始位置 8 * @param high 9 * 递归排序过程中的结束位置 10 */ 11 private static void quickSort_v2(int[] arr, int low, int high) { 12 if (low < high) { 13 int index = getIndex(arr, low, high); 14 quickSort_v2(arr, low, index - 1); 15 quickSort_v2(arr, index + 1, high); 16 } 17 } 18 19 private static int getIndex(int[] arr, int low, int high) { 20 int base = arr[low]; 21 while (low < high) { 22 while (low < high && base <= arr[high]) { 23 high--; 24 } 25 if (low < high) { // 这里的判断可以少进行一次交换 26 arr[low] = arr[high]; 27 low++; 28 } 29 30 while (low < high && base >= arr[low]) { 31 low++; 32 } 33 if (low < high) { 34 arr[high] = arr[low]; 35 high--; 36 } 37 } 38 arr[low] = base; 39 return low; 40 }