选择第k大问题
1 锦标赛算法
2 选第k小的分治算法
3 选最大最小值 (分治算法)
(BFPRT算法 对快速排序的改进,每次选取中位数)
锦标赛算法
public static int arraychampionship(int[] array){
int n=rebuildNum(array.length);
int[] A=new int[2*n];
for (int i=n;i<2*n;i++){
if(i<n+array.length){
A[i]=array[i-n];
}
else{
A[i]=-1;
}
}
int n2;
for(n=16,n2=0;n>1;n/=2,n2++){
for (int i = n; i < 2*n-1; i += 2) {
if (A[i] > A[i + 1]) {
A[i / 2] = A[i];
} else {
A[i / 2] = A[i + 1];
}
}
}
int i=1;
int max2=-1;
int[] a=new int[n2];
for(int k=0;k<n2;k++){
if(A[2*i]==A[1]){
a[k]=A[2*i+1];
i=2*i;
}
else{
a[k]=A[2*i];
i=2*i+1;
}
if(max2<a[k]){
max2=a[k];
}
}
return max2;
}
public static int rebuildNum(int num){
int max = 1 << 30;
int n = num - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return n < 0 ? 1 : (n >= max ? max : n + 1);
}
选第k小的分治算法
public static int arraychoosekst(int[] array,int low ,int high, int key){
int i=low,j=high,temp=array[i];
if(low<high){
do{
while(array[j]>temp&i<j){
j--;
}
if(i<j) {
array[i] = array[j];
i++;
}
while(array[i]<temp&i<j){
i++;
}
if(i<j){
array[j]=array[i];
j--;
}
}while(i!=j);
}
if (i-low+1==key){
return temp;
}
if(key>i-low+1){
return arraychoosekst(array,i+1,high,key-(i-low+1));
}
else{
return arraychoosekst(array,low,i-1,key);
}
}
选最大最小值 (分治算法)
public static void arraypartionget(int[] array,int s,int e,int[] max,int[] min){
int i;
if(e-s<=1){
if(array[e]>array[s]){
if(array[e]>max[0]){
max[0]=array[e];
}
if(array[s]<min[0]){
min[0]=array[s];
}
}
else {
if(array[e]<min[0]){
min[0]=array[e];
}
if(array[s]>max[0]){
max[0]=array[s];
}
}
return;
}
i=s+(e-s)/2;
arraypartionget(array,s,i,max,min);
arraypartionget(array,i+1,e,max,min);
}