java实现快速排序(详细注释)
1 /** 2 * 快速排序1 3 * @param arr 4 * @param low 5 * @param high 6 */ 7 public static void quickSort1(int[] arr, int low, int high) { 8 int i , j ,pivot; 9 if (low >= high){ 10 return; 11 } 12 i = low; 13 j = high; 14 //选取最左边的点为基准点 15 pivot = arr[low]; 16 while (i < j){ 17 //先从右往左遍历,j下标对应的值>基准点对应的值,则j继续往左走 18 while (i < j && arr[j] > pivot){ 19 j--; 20 } 21 //j下标对应的值<基准点对应的值,则把此时j下标对应的值赋给i处的值,i再后移一位 22 if (i < j){ 23 arr[i++] = arr[j]; 24 } 25 //再从左往右遍历,i下标对应的值<基准点对应的值,则i继续往右走 26 while (i < j && arr[i] < pivot){ 27 i++; 28 } 29 //i下标对应的值>基准点对应的值,则把此时i下标对应的值赋给j处的值,j再前移一位 30 if (i < j){ 31 arr[j--] = arr[i]; 32 } 33 } 34 //当i==j时,跳出循环,把基准点归到i处,此时一次分区完成 35 arr[i] = pivot; 36 //递归,再分区基准点左边及右边 37 quickSort1(arr,low,i-1); 38 quickSort1(arr,i+1,high); 39 } 40 41 42 /** 43 * 快速排序2 44 * @param arr 45 * @param low 46 * @param high 47 */ 48 public static void quickSort2(int[] arr, int low, int high){ 49 if(low>=high){ 50 return; 51 } 52 //选取最右边的点为基准点 53 int pivot = arr[high]; 54 //从左往右遍历 55 int i = low; 56 int j = low; 57 while (j <= high){ 58 //当指针j位置的值比基准点小时,交换arr[i]和arr[j] 59 if (arr[j] < pivot){ 60 int temp = arr[i]; 61 arr[i] = arr[j]; 62 arr[j] = temp; 63 i++; 64 } 65 j++; 66 } 67 //j>high跳出循环,此时基准点仍处于最右侧,i的左边是比基准点小的元素,i及i右边是是除了基准点外都比基准点大的元素,交换基准点和i位置的元素,此时i左面都比基准点小,右面都比基准点大 68 arr[high] = arr[i]; 69 arr[i] = pivot; 70 ////递归,再分区基准点左边及右边 71 quickSort2(arr,low,i-1); 72 quickSort2(arr,i+1,high); 73 } 74 75 public static void main(String[] args) { 76 int[] arr = {2,8,13,4,0,1,3,21,9,7,5,6}; 77 // QuickSort.quickSort1(arr,0,arr.length-1); 78 QuickSort.quickSort2(arr,0,arr.length-1); 79 System.out.println(Arrays.toString(arr)); 80 }
1.最好情况时间复杂度为O(nlogn),最坏情况时间复杂度为O(n^2),平均时间复杂度为O(nlogn)
2.没有额外申请内存空间,空间复杂度为O(1),是原地排序算法
3.不是稳定的排序算法,比如[1, 9, 1, 8, 9, 3, 7],运用方法2,当j指向元素3时,i指向第一个9,此时i和j交换,第一个9会换到第二个9的后面,前后位置改变了
(稳定性:一组数中相同的两个数,排序完成后前后位置保持不变)
,此时
[, Cǐ shí]
副词now; this moment