Randomized Select算法
- 中位數問題 等價於 集合中第 i 個順序統計量問題(不考慮奇偶性,偶數取下界)
- 如果用排序複雜度爲 nlgn
- Randomized Select算法是一個期望複雜度爲線性的算法
- 每次以快排的樞紐劃分數組 [ begin....k...end ] 如果target<k,則在 [ begin....k-1 ]遞歸查找
package com.zfy.algr;
public class Test {
static int partition(int[] arr,int begin, int end){//快排的樞紐劃分改版
int tmp = arr[end];
int left = begin-1;//向右滑動錄入比tmp小的數
for (int i = begin; i < end; i++) {
if(arr[i]<=tmp){
left++;
int change = arr[left];
arr[left] = arr[i];
arr[i] = change;
}
}
int change = arr[left+1];
arr[left+1] = arr[end];
arr[end] = change;
return left+1;
}
static int randomized_select(int[] arr, int begin, int end, int target){//Randomized Select算法
if(begin == end){
return arr[begin];
}
int q = partition(arr,begin,end);//第q小的
int k = q-begin;
if(k == target){
return arr[k];
}else if(k>target){
return randomized_select(arr,begin,k-1,target);
}else {
return randomized_select(arr,k+1,end,target-k);
}
}
public static void main(String[] args) {
int[] array = {9,6,8,7,2,3,1,4,5};
for (int i = 1; i < 8; i++) {
System.out.println(randomized_select(array,0,8,i-1));
}
}
}
- 這種分割有時候同快排一樣最壞情況下以最大或者最小結點分割會導致效率不高,由此出現一種改進分割的算法,select算法
select算法:
- 以5個元素爲1組 劃分 集合
- 找出每組5個元素中的中位數
- 遞歸select算法找出這些中位數的中位數 k
- 上述過程時間複雜度本質爲0(n)級別的
- 然後以k爲樞紐運行Randomized Select算法的遞歸部分
- 由於k可以保證劃分的最低下限(每個中位數保證有一半元素大於或小於它,所以中位數的中位數保證大於或小於的結點儘可能接近一半),故算法在最壞情況下也是0(n)級別的複雜度(不會證明就不獻醜了)