1.递归行为时间复杂度估算
a子问题调用了几次
N/b子问题的规模
d其余的时间复杂度
2.归并排序
O(NlogN) O(N)
递归过程实现
// 递归方法实现
public static void mergeSort1(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
process(arr, 0, arr.length - 1);
}
// 请把arr[L..R]排有序
// l...r N
// T(N) = 2 * T(N / 2) + O(N)
// O(N * logN)
public static void process(int[] arr, int L, int R) {
if (L == R) { // base case
return;
}
int mid = L + ((R - L) >> 1);
process(arr, L, mid);
process(arr, mid + 1, R);
merge(arr, L, mid, R);
}
public static void merge(int[] arr, int L, int M, int R) {
int[] help = new int[R - L + 1];
int i = 0;
int p1 = L;
int p2 = M + 1;
while (p1 <= M && p2 <= R) {
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
// 要么p1越界了,要么p2越界了
while (p1 <= M) {
help[i++] = arr[p1++];
}
while (p2 <= R) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[L + i] = help[i];
}
}
非递归过程实现
// 非递归方法实现
public static void mergeSort2(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
// 步长
int mergeSize = 1;
while (mergeSize < N) { // log N
// 当前左组的,第一个位置
int L = 0;
while (L < N) {
if (mergeSize >= N - L) {
break;
}
int M = L + mergeSize - 1;
int R = M + Math.min(mergeSize, N - M - 1);
merge(arr, L, M, R);
L = R + 1;
}
// 防止溢出
if (mergeSize > N / 2) {
break;
}
mergeSize <<= 1;
}
}
小和问题
转化为一个数的右边有多少个数比这个数大
待补充
逆序对问题
待补充
3.快排
1.根据<=num做划分(不需要有序)
2.根据<、=、>三者划分(不需要有序)
荷兰国旗问题
代码中的partition
注意当i大于num时,i是不动的。
实质:
待定区域要么被i推着走,要么被>区域推着走
终止条件:当大于区域和i装上的时候,过程停止。
3.快排1.0
O(N^2)
4.快排2.0
O(N^2)
5. 快排3.0
O(NlogN)
随机选一个数放到最后,作为划分值。
public class quickSort {
public static void quickSort3(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort3(arr, 0, arr.length - 1);
}
public static void quickSort3(int[] arr,int L,int R){
if(L<R){
swap(arr, L+(int)(Math.random()*(R-L+1)),R);//随意找一个数放到数组的最后(要比较的数)
int[] p = partition(arr,L,R);//荷兰国旗问题,返回的是一个长度为2的数组,0位置是第一个等于最后数字的数,1位置是最后一个等于最后数字的数
quickSort3(arr,L,p[0]-1);//前面部分快排
quickSort3(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};
}
public static void swap(int[]arr ,int i,int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args) {
int[] res = new int[]{1,3,5,3,2,5,6,3};
quickSort3(res);
for (int i = 0; i < res.length; i++) {
System.out.println(res[i]);
}
}
}