这里写了个快速排序的工具类,简单写一下它的工作方式吧。
有数组[4,3,5,2]如图,
1.取第一个元素赋给临时变量v,循环结束时,v左边的都小于v,v右边的都大于v;
2.以v为中心划分,得到两个小数组,递归1;
快速排序虽然使用了递归,但是由于是log(n),所以栈的深度并不高,就算是Integer.MAX_VALUE的数组,栈顶多31层。
它是最常用的排序算法了吧应该,有人说堆排序和快速排序都是O(nlogn),堆没有递归,所以堆排序比快速排序更好。有没有递归并不能决定一个算法的好坏,其实好与不好要看使用场景的,如果仅仅是对一个数组排一下序,选快速排序;如果要一直维护一个有序队列,选堆排序。
快速排序的理想时间复杂度是O(nlogn),为什么说是理想呢,因为如果待排序的数组正好是倒序的,快速排序的分治策略就很差了,它总是把左右数组分为大小为n-1和0两个,所以递归的深度一下子变成了n,如果数组长度为1000000,直接就栈溢出了,并且时间复杂度成了O(n^2)。所以快排也是不稳定的排序算法,为了防止这样的情况发生,通常是随机取个比较基准,而不是每次都取首元素,我觉得每次都取中间的也是不错的选择。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package structure;
import java.util.Arrays;
public abstract class QuickSort {
public static void sort(Object[] array) { sort(array, 0, array.length); }
public static void sort(Object[] array, int h, int t) { if (h < t) { Object v = array[h]; int i = h, j = t - 1; while (i < j) { while (i < j && bigger(array[j], v)) j--; array[i] = array[j]; while (i < j && bigger(v, array[i])) i++; array[j] = array[i]; } array[i] = v; sort(array, h, i); sort(array, i + 1, t); } }
private static boolean bigger(Object a, Object b) { return ((Comparable) a).compareTo(b) >= 0 ? true : false; }
public static void main(String[] args) { int len = 10; Integer[] a = new Integer[len]; for (int i = 0; i < len; i++) { a[i] = len - i; } a[0] = 3; QuickSort.sort(a); Arrays.stream(a).forEach(System.out::println); } }
|