public class QuickSort { private static int partition(Comparable[] a, int low, int high) { // 下面使用++i和--j的形式,因此i和j的定义如下 int i = low; int j = high + 1; // 切分元素保存下来 Comparable v = a[low]; while (true) { // 从左到右扫描,直到遇到大于等于v的元素为止 while (less(a[++i], v)) { if (i == high) { break; } } // 从右到左扫描,直到遇到小于等于v的元素为止 while (less(v, a[--j])) { if (j == low) { break; } } // 由于指针是先自增,所以先判断指针是否相遇,相遇就退出while if (i >= j) { break; } // 若没有相遇就交换元素 swap(a, i, j); } // 切分元素交换到合适的位置 swap(a, low, j); return j; } }
最后为什么是low和j交换(而不是和i),切分元素就换到了合适的位置?
看图说明一切
最后一次交换i = 5, j = 6,while循环继续,所以i变成6,j变成5,break跳出。将i处的L与切分元素K交换肯定是不对的(这样比K大的L排在了切分元素的左边),所以应该用位置j处的E和切分元素交换,结果如上头最后一行所示,是正确的。
接着写快速排序的代码就顺理成章了。
public static void sort(Comparable[] a) { // 随机打乱数组,大大减小最坏情况的概率 shuffle(a); sort(a, 0, a.length - 1); } private static void shuffle(Comparable[] a) { // asList返回的是实际上是ArrayList,而ArrayList的底层是数组,所以打乱了b,a也被打乱了 Listb = Arrays.asList(a); Collections.shuffle(b); } private static void sort(Comparable[] a, int low, int high) { // 当只有一个元素时,不能再切分,直接返回 if (high