快速随机排序的思路是从一个数组中随机选择一个主元,然后将这个主元放到数组的最后.循环数组时,先定义一个指针,发现了比主元小的元素,如果指针和循环下标相同
则只是把指针自增,如果发现循环下标不同则将循环下标与指针位置交换,这样做的目的是始终保证指针左边的元素小于主元,最后循环结束将主元与指针位置交换.这样
就将数组分成了left pivot right.然后再递归left,right.
private static void quickInternal(int[] a, int l, int r) { // 终止条件 if (l >= r) { return; } // 查找分区点 int q = partition(a, l, r); quickInternal(a, l, q - 1); quickInternal(a, q + 1, r); } // 排序 private static int partition(int[] a, int l, int r) { if (a.length == 1) { return 0; } int random; if (l == 0) { random = new Random().nextInt(r + 1); } else { // 不为0 则 random = new Random().nextInt(r - l) + l; } if (random != r) { int tmp = a[random]; a[random] = a[r]; a[r] = tmp; } int pivot = a[r]; int m = l; for (int j = l; j < r; j++) { if (a[j] < pivot) { // 如果相等,不交换,同时后移一位 if (m == j) { m++; } else { int temp = a[m]; a[m++] = a[j]; a[j] = temp; } } } int temp = a[m]; a[m] = a[r]; a[r] = temp; return m; }
以下提供一个测试方法.
public static void main(String[] args) { Random random = new Random(); while (true) { int length = random.nextInt(10); int[] arr = new int[length]; int[] arr2 = new int[length]; for (int x = 0; x < length; x++) { int i = random.nextInt(10); arr[x] = i; arr2[x] = i; } quickInternal(arr, 0, arr.length - 1); Arrays.sort(arr2); boolean equals = Arrays.equals(arr2, arr); System.out.println(equals); if (!equals) { break; } } }