1. 荷兰国旗问题
现有红白蓝三个不同颜色的小球,乱序排列在一起,请重新排列这些小球,使得红白蓝三色的同颜色的球在一起。
在一个数组中 arr 中,给定一个数 X,使得数组中 < X 的 在左侧, == X 的在中间, >X的在右侧
public void netherlandsFlag(int[] arr, int X) {
int less = 0, great = arr.length - 1, i = 0;
while (i <= great) {
if (arr[i] < X) {
swrap(arr, less++, i++);
} else if (arr[i] > X) {
swrap(arr, great--, i);
} else {
i++;
}
}
}
private void swrap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
2. 快排
public void sort(int[] arr) {
process(arr, 0, arr.length - 1);
}
private void process(int[] arr, int L, int R) {
if (L > R) {
return;
}
if (L == R) {
return;
}
int[] re = partition(arr, L, R);
process(arr, L, re[0] - 1);
process(arr, re[1] + 1, R);
}
public int[] partition(int[] arr, int L, int R) {
int less = L, great = R - 1, i = L, X = arr[R];
while (i <= great) {
if (arr[i] < X) {
swrap(arr, less++, i++);
} else if (arr[i] > X) {
swrap(arr, great--, i);
} else {
i++;
}
}
swrap(arr, great + 1, R);
return new int[]{less, great + 1};
}
3. 随机快排
将快排的选择比较值随机化
public void sort(int[] arr) {
process(arr, 0, arr.length - 1);
}
private void process(int[] arr, int L, int R) {
if (L > R) {
return;
}
if (L == R) {
return;
}
swrap(arr, (int)(Math.random() * (R - L + 1)) + L, R);
int[] re = partition(arr, L, R);
process(arr, L, re[0] - 1);
process(arr, re[1] + 1, R);
}
4. 随机快排非递归版本
public void sort2(int[] arr) {
if (arr.length <= 1) {
return;
}
Stack<int[]> stack = new Stack<>();
stack.push(new int[]{0, arr.length - 1});
while (!stack.isEmpty()) {
int[] op = stack.pop();
if (op[0] < op[1]) {
swrap(arr, (int)(Math.random() * (op[1] - op[0] + 1)) + op[0], op[1]);
int[] op1 = partition(arr, op[0], op[1]);
stack.push(new int[]{op[0], op1[0] - 1});
stack.push(new int[]{op1[1] + 1, op[1]});
}
}
}