快速排序
经典快排根据荷兰国旗划分数组给定一个数组arr,和一个数num,请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。,每次划分都拿最后一个数进行划分每次把小于等于num[R]的数放在数组的左半部分,大于num[R]的数放在数组的右半部分。记录等于num[R]的下标。
先讲述一下荷兰国旗的问题
public static int[] flag(int[] arr,int num){
//这个变量是小于num的下标
int less=-1;
int cur=0;
//大于num的下标
int more=arr.length;
while (cur<more){
if (arr[cur]==num){
cur++;
}else if (arr[cur]<num){
swap(arr,++less,cur++);
}else {
swap(arr,--more,cur);
}
}
return arr;
}
private static void swap(int[] arr, int i, int j) {
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
经典快排
同样是拿最后一个数进行划分返回等于最后一个数的两个下标最后把大于区域第一个数和最后一个数进行划分重复子过程直到数组有序两种写法都可以区别只有一行代码。
public static void partionionArr(int[] arr){
partionionArrary(arr,0,arr.length-1);
System.out.println();
}
private static void partionionArrary(int[] arr, int L, int R) {
if (R>L){
// int[] p =partition(arr,L,R);
int[] p = partitionQuick(arr, L, R); //经典快排
partionionArrary(arr,L,p[0]-1);
partionionArrary(arr,p[1]+1,R);
}
}
public static int[] partitionQuick(int[] arr,int L,int R){
int less=L-1;
int more=R+1;
int target=arr[R]; //每次拿最后一个数进行划分数组
while (L<more){
if (arr[L]==target){
L++;
}else if (arr[L]<target){
swap(arr,++less,L++);
}else {
swap(arr,--more,L);
}
}
//返回等于区域的位置下标
return new int[]{less+1,more-1};
}
public static int[] partition(int[] arr, int l, int r) {
int less = l - 1;
//最后一个数不参与遍历
int more = r;
while (l < more) {
if (arr[l] < arr[r]) {
swap(arr, ++less, l++);
} else if (arr[l] > arr[r]) {
swap(arr, --more, l);
} else {
l++;
}
}
swap(arr, more, r);//把最后一个数和大于target的第一个数交换
// //返回等于区域的位置下标
return new int[] { less + 1, more };
}
private static void swap(int[] arr, int i, int j) {
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
经典快排的问题
经典快排如果是在数组有序的情况下===(最坏的情况下)===时间复杂度是O(N^2)以为子过程的规模两个不相等。一般情况下时间复杂度为N*(LogN);
随机快排
随机快排是在其中随机选择一个数去划分数组把这个随机选的数和最后的位置交换在进行经典快排一样的操作。所有随机快排的时间复杂度为一个数学的长期期望值是一个固定的表达式N*(LogN);
public static void partionionArr(int[] arr){
partionionArrary(arr,0,arr.length-1);
System.out.println();
}
private static void partionionArrary(int[] arr, int L, int R) {
if (R>L){
swap(arr,L+(int) Math.random()*(R-L+1),R);
int[] p = partition(arr, L, R);
partionionArrary(arr,L,p[0]-1);
partionionArrary(arr,p[1]+1,R);
}
}
public static int[] partition(int[] arr, int l, int r) {
int less = l - 1;
int more = r;
while (l < more) {
if (arr[l] < arr[r]) {
swap(arr, ++less, l++);
} else if (arr[l] > arr[r]) {
swap(arr, --more, l);
} else {
l++;
}
}
swap(arr, more, r);
return new int[] { less + 1, more }; 把最后一个数和大于target的第一个数交换
}