利用隨機化的思想求n個元素當中第k小的元素

        傳統的求n個元素當中第k小的元素採用分置的思想,即取一確定數v(一般取44),順次比較n個數與該確定數(44)的大小,將小於該數的存入數組A1,等於該數的存入數組A2,大於該數的存入數組A3;接着比較k與三個數組的長度,若|A1|>=k,則重複上過程;若|A1|+|A2|>=k,則返回該確定數(即44);若|A1|+|A2|<k,則重複上過程,此時求A3數組當中第k-|A1|-|A2|小的元素。

         該算法當中選取的確定數44較大,當參與比較的數較小時,分置思想並未得到體現,故採用隨機化的思想對該算法進行優化。

         具體爲,隨機的從n個元素當中選擇一個數v作爲分置的邊界,其餘不變,具體代碼如下:

import java.util.ArrayList;
import java.util.Random;


public class RandomSelect {
	
	public RandomSelect(){
		
	}
	
	public int RSelect(int [] a, int low, int hight, int k) {
		Random random = new Random();
		int v = random.nextInt(hight-1-low-1+1)+low;
		int x = a[v];
		
		
		ArrayList<Integer> a1 = new ArrayList<>();
		ArrayList<Integer> a2 = new ArrayList<>();
		ArrayList<Integer> a3 = new ArrayList<>();
		
		for(int i=0;i<a.length;i++){
			if(a[i]<x)
				a1.add(a[i]);
			if(a[i]==x)
				a2.add(a[i]);
			if(a[i]>x)
				a3.add(a[i]);
		}
		
		if(a1.size() >= k){
			int [] a11 = new int [a1.size()];
			for(int i=0;i<a1.size();i++){
				a11[i] = a1.get(i);
			}
			return RSelect(a11, 1, a11.length, k);
		}
		
		if(a1.size()+a2.size() >= k){
			return x;
		}
		
		if(a1.size()+a2.size()+a3.size() >= k){
			int [] a31 = new int [a3.size()];
			for(int i=0;i<a3.size();i++){
				a31[i] = a3.get(i);
			}
			return RSelect(a31, 1, a31.length, k-a1.size()-a2.size());
		}	
		
		else 
			return 0;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章