快速排序, 应用场景: 数据量大且为线性结构时。
短处:有大量重复数据的时候,性能不好
单向链式结构处理性能不好(一般来说,链式都不使用)
一次排序过程:
1)取一个高位指针和一个低位指针, 暂存低位指针的值temp
2)移动高位指针,如果值比Temp大,继续移动不做处理,如果比temp小,则取出来放在低位指针的位置上
3)然后移动低位指针,如果值比temp小则继续移动不做处理,如果比temp大,则取出来放到高位指针的位置
4)然后再移动高位指针,与步骤2相同
5)当有值比temp小时, 把它的值赋给低位指针
6)再移动低位指针
7)如此变换直到两个指针重合
8)把temp的值放在指针重合的位置上
9)这样,经过一轮变换后, 我们可以固定一个数(31)的位置, 它前面的都比它小,它后面的都比它大。
然后我们可以利用递归的思想, 对前面部分和后面部分分别排序。
因为每次排序最坏情况下会执行n次, 所以快排的时间复杂度为n*log2N (n 乘以 log以2为底的n的对数 )
看下代码实现:
1 public static void quickSort(int[] array, int begin, int end) { 2 if(begin >= end) { 3 return; 4 } 5 int low = begin; 6 int high = end; 7 //先找到低位指针的值temp 8 int temp = array[low]; 9 boolean direction = true;//定义true为高位指针从右向左移动 10 L1: 11 while (low < high) { 12 //查看高位指针的值, 与temp比较 13 //如果比temp大,高位指针前移一位 14 //如果比temp小,高位指针前移一位且把它的值放在低位指针的位置,然后移动低位指针 15 if (direction) { 16 for (int i = high; i > low; i--) { 17 if (array[i] <= temp) { 18 array[low] = array[i]; 19 low++; 20 high=i; 21 //执行到这里后我们要改变策略,开始移动低位指针 22 //所以我们需要定义一个方向direction,在这里取反 23 direction = !direction; 24 //然后还需要让程序回到if (direction)之前的位置 25 //这里不能用break, 因为会直接跳出去 26 //所以我们在if (direction)之前写个标记 27 continue L1; 28 } 29 30 } 31 //如果if里面的代码从未进去,让两个指针重合 32 high = low; 33 //移动低位指针的逻辑 34 }else { 35 //查看低位指针的值,和temp比较 36 //如果比temp小,指针后移一位 37 //如果比temp大, 指针后移一位,且把它的值放在高位指针的位置,然后操作高位指针 38 for (int i = low; i < high; i++) { 39 if (array[i] >= temp) { 40 array[high] = array[i]; 41 high--; 42 low = i; 43 //执行到这里后我们要改变策略,开始移动高位指针 44 direction = !direction; 45 continue L1; 46 } 47 } 48 //如果if里面的代码从未进去,让两个指针重合 49 low = high; 50 } 51 52 } 53 //while 循环执行完之后,两个指针重合,low==high 54 //我们把temp的值放在low的位置 55 //此时low(high)左边值的都比它小,右边值的都比它大 56 array[low] = temp; 57 quickSort(array, begin, low-1); 58 quickSort(array, low+1, end); 59 }
注意这里调用递归的地方
我刚开始写的时候写成了这样
quickSort(array, 0, low-1);
quickSort(array, low+1, array.length-1);
结果运行起来总是报stackOverFlowError.
之所以会这样写,还是没有理解递归的思想。虽然我们整个方法里没有地方去对begin/ end赋值, 但因为递归调用(low-1和low+1)被传进去,所以begin和end的取值时不断在变化的, 不能hardcode.
看看方法调用及排序结果:
1 @Test 2 fun test(){ 3 val array = intArrayOf(4, 7, 91, 10, 21, 14, 22, 1, 62, 103, 5, 10) 4 quickSort(array, 0, array.size - 1) 5 for (i in array.indices) { 6 print(array[i].toString() + " ") 7 } 8 }