/** * ----------------------快速排序---------------------------------- * * 原地、时间复杂度平均为O(NlgN),最差情况为O(N^2),只要保证随机切分,就能保证平均效率 * * 先切分,再分别排序 */ Random random = new Random(); @Test public void quickSort() { int[] array = { 5, 2, 4, 6, 1, -1, 8, 7, 3, 99, 0, 78 }; quickSort(array, 0, array.length - 1); System.out.println(Arrays.toString(array)); } private void quickSort(int[] array, int i, int j) { if (i < j) { // 通过位置为p的值对数组进行切分,左边小于等于该值,右边大于该值,并返回切分点位置p //这里采用随机切分,来保证快排的效率 int p = randomPartition(array, i, j); // 对左右两部分分别进行排序 quickSort(array, i, p - 1); quickSort(array, p + 1, j); } } //进行随机切分 private int randomPartition(int[] array, int i, int j) { // 在i-j间进行随机切分,并获取随机切分的位置 int k = random(i, j); //将随机切分的值和末尾元素交换 exchange(array, k, j); //利用末尾(即随机切分的值)进行切分 return partition(array, i, j); } private int random(int i, int j) { return random.nextInt(j - i + 1) + i; } private int partition(int[] array, int i, int j) { // 作为切分点的值 int key = array[j]; // 记录x作为左边部分与切分点位置的分界点 int x = i - 1; // 对除了切分点j位置的其他位置进行筛选,碰到小于等于key的值,则将x右移动一位,并将这个值与x位置互换,表示将这个值放到x左边,并扩张切分左半部分的区域。 for (int k = i; k < j; k++) { if (array[k] <= key) { exchange(array, k, ++x); } } // 结束筛选之后,需要将切分点从末尾j插入到合适位置 exchange(array, x + 1, j); // 返回切分点位置 return x + 1; } private void exchange(int[] array, int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; }