1、计算中点时为了防止相加溢出
mid = L+((R—L)>>1)
2、使用二分法思想,递归实现查找数组的最大最小值
//以查找最大值为例
public class Code08
public class GetMax{
public int getmax(int[] arr){
return process(0,arr.length-1,arr);
}
public static int process(int L,int R,int[] arr){
if(L==R){
return arr[L];}//此处为递归退出条件
int mid = L+((R-L)>>1);
int LeftMax = process(L,mid,arr);
int RightMax = process(mid+1,R,arr);
return Math.max(LeftMax,RightMax);
}
}
3、归并排序
归并排序:将小部分的有序部分合并为大的有序序列
①采用递归思想,先局部排序process再两两归并merge
public class GetMax{
public int getmax(int[] arr){
return process(0,arr.length-1,arr);
}
public static int process(int L,int R,int[] arr){
int mid = L+((R-L)>>1);
process(L,mid,arr);
process(mid+1,R,arr);
merge(L,R,mid,arr);
}
public static int merge(int L,int R,int mid,int[] arr){
int[] help = new int [R-L+1];
int x = L;
int y= mid+1;
int p=0;
if(L==R) return;
while(x<=mid&&y<=R){
arr[x]>arr[y]?help[p++]=arr[y++]:help[p++]=arr[x++];
}
while(x<=mid){
help[p++]=arr[x++];
}
while(y<=mid){
help[p++]=arr[y++];
}
}
for(i=0,i<=R-L,i++){
arr[l++]=help[i]
}
}
题目三:荷兰国旗
1、给有一个数组arr和一个num,让数组中小于等于num的数在数组的左侧,大于num 的数在数组的右侧。
2、给一个数组arr和一个num,排序将小于num的数组排在数组的左侧,等于num的数排在数组的中间,大于num的数排在数组的右边
思想:[i]<num.,[i]与小于区下一个换,i原地不变,小于区扩大,
[i]=num,i++;
[i]>num,[i]与大于区下一个换,大于区扩大,i原地不变
public class TriColorFlag{
public static void tricolorflag (int[] arr,int num){
if(arr.length<2){
return;
}
int ls = 0;
int rs = arr.length-1;
int i=0;
while(i<rs){
if(arr[i]<num){
swap(arr,i,ls);
ls++;
i++;
}
else if(arr[i]==num){
i++;
}
else{
swap(arr,i,rs);
rs--;
}
}
}
public static void swap(int[] arr,int L,int R){
arr[L]=arr[L]^&arr[R];
arr[R]=arr[L]^&arr[R];
arr[L]=arr[L]^&arr[R];
}
}
快排
快排1.0,每次找到一个数的最最终位置(一般都是选用数组最后一个数),然后左右侧不断递归
快排2.0:利用荷兰国旗问题替代1.0中的比较算法,这样就可以一次解决一批数字(等于划分值
快排3.0:随机选择一个数作为划分数
| |||||||