速排序1.0/2.0/3.0+荷兰国旗问题
package SortAlgorithm;
import java.util.Arrays;
public class FastSort {
public FastSort(){
}
// 快速排序1.0版本
public void fast1_0(int[] arr,int L,int R,int num){
if(arr == null || arr.length < 2 || R == L){
return;
}
int small = -1; // 小于num的区域
int big = R; // 大于num的区域 注意:每次处理的是传入的右边界,而不是原始数组arr的右边界
int i = 0; // arr下标
while(i < big){ // 这要难想到,big后面已经处理过了,就不用处理了,不然重复处理会搞错
if(arr[i] <= num){
int tmp = arr[i];
small++;
if(small >= big){ // 注意边界
small--;
break;
}
arr[i] = arr[small];
i++;
arr[small] = tmp;
}
else{
int tmp = arr[i];
big--;
if(big <= small){ // 注意边界
big++;
break;
}
arr[i] = arr[big];
arr[big] = tmp;
}
}
//
// System.out.print(small + "\t");
// System.out.println(big);
if(big < R){
int tmp = arr[big];
arr[big++] = num;
arr[R] = tmp;
}
// System.out.print(small + "\t");
// System.out.println(big);
small = small >=L ? Math.min(small,R) : L;
big = big <= R ? Math.max(big,L) : R;
// System.out.print(small + "\t");
// System.out.println(big);
fast1_0(arr,L,small,arr[small]);
fast1_0(arr,big,R,arr[R]);
}
// 快速排序2.0版本
public void fast2_0(int[] arr,int L,int R,int num){
if(arr == null || arr.length < 2 || R == L){
return;
}
int small = -1; // 小于num的区域
int big = R + 1; // 大于num的区域 注意:每次处理的是传入的右边界,而不是原始数组arr的右边界
int i = 0; // arr下标
while(i < big){ // 这要难想到,big后面已经处理过了,就不用处理了,不然重复处理会搞错
if(arr[i] == num){
i++;
}
else if(arr[i] < num){
int tmp = arr[i];
small++;
if(small >= big){
small--;
break;
}
arr[i] = arr[small];
i++;
arr[small] = tmp;
}
else{
int tmp = arr[i];
big--;
if(big <= small){
big++;
break;
}
arr[i] = arr[big];
arr[big] = tmp;
}
}
// System.out.print(small + "\t");
// System.out.println(big);
small = small >=L ? Math.min(small,R) : L;
big = big <= R ? Math.max(big,L) : R;
// System.out.print(small + "\t");
// System.out.println(big);
fast2_0(arr,L,small,arr[small]);
fast2_0(arr,big,R,arr[R]);
}
// 快速排序3.0版本
public void fast3_0(int[] arr,int L,int R,int num){
if(arr == null || arr.length < 2 || R == L){
return;
}
int small = -1; // 小于num的区域
int big = R + 1; // 大于num的区域 注意:每次处理的是传入的右边界,而不是原始数组arr的右边界
int i = 0; // arr下标
num = arr[L + (int)(Math.random() * (R - L + 1))];
// int index = L + (int)(Math.random() * (R - L + 1));
// num = arr[index];
// arr[index] = arr[R];
// arr[R] = num;
while(i < big){ // 这要难想到,big后面已经处理过了,就不用处理了,不然重复处理会搞错
if(arr[i] == num){
i++;
}
else if(arr[i] < num){
int tmp = arr[i];
small++;
if(small >= big){
small--;
break;
}
arr[i] = arr[small];
i++;
arr[small] = tmp;
}
else{
int tmp = arr[i];
big--;
if(big <= small){
big++;
break;
}
arr[i] = arr[big];
arr[big] = tmp;
}
}
// System.out.print(small + "\t");
// System.out.println(big);
small = small >=L ? Math.min(small,R) : L;
big = big <= R ? Math.max(big,L) : R;
// System.out.print(small + "\t");
// System.out.println(big);
fast3_0(arr,L,small,arr[small]);
fast3_0(arr,big,R,arr[R]);
}
// 荷兰国旗问题
public void netherlandsFlag(int[] arr,int L,int R,int num){
if(arr == null || arr.length < 2 || R == L){
return;
}
int small = -1; // 小于num的区域
int big = R + 1; // 大于num的区域 注意:每次处理的是传入的右边界,而不是原始数组arr的右边界
int i = 0; // arr下标
while(i < big){ // 这要难想到,big后面已经处理过了,就不用处理了,不然重复处理会搞错
if(arr[i] == num){
i++;
}
else if(arr[i] < num){
int tmp = arr[i];
small++;
if(small >= big - 1){
small--;
return;
}
arr[i] = arr[small];
i++;
arr[small] = tmp;
}
else{
int tmp = arr[i];
big--;
if(big <= small + 1){
big++;
return;
}
arr[i] = arr[big];
arr[big] = tmp;
}
}
}
public static void main(String[] args) {
int [] arr1 = {3,5,2,7,9,1,4,6,0,8,3,4,4,3,5,3,1,2,0,5,4,7};
int [] arr2 = {3,5,2,7,9,1,4,6,0,8,3,4,4,3,5,3,1,2,0,5,4,7};
int [] arr3 = {3,5,2,7,9,1,4,6,0,8,3,4,4,3,5,3,1,2,0,5,4,7};
int [] arr4 = {3,5,2,7,9,1,4,6,0,8,3,4,4,3,5,3,1,2,0,5,4,7};
FastSort fastSort = new FastSort();
// 快速排序1.0版本
fastSort.fast1_0(arr1,0,arr1.length - 1,arr1[arr1.length - 1]);
// 快速排序2.0版本
fastSort.fast2_0(arr2,0,arr2.length - 1,arr2[arr2.length - 1]);
// 快速排序3.0版本
fastSort.fast3_0(arr3,0,arr3.length - 1,arr2[arr3.length - 1]);
// 荷兰国旗问题
fastSort.netherlandsFlag(arr4,0,arr4.length - 1,arr3[arr4.length - 1]);
System.out.println(Arrays.toString(arr1));
System.out.println(Arrays.toString(arr2));
System.out.println(Arrays.toString(arr3));
System.out.println(Arrays.toString(arr4));
}
}
输出
[0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 7, 8, 9]
[0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 7, 8, 9]
[0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 7, 8, 9]
[3, 5, 2, 7, 1, 4, 6, 0, 8, 3, 4, 4, 3, 5, 3, 1, 2, 0, 5, 4, 7, 9]