演算法:利用分治演算法求解N個元素中的第M大元素

坤輿湖畔的萬某某發表於2020-10-25

題目描述:

設計一個分治演算法,在一個具有n個元素的陣列中,尋找第5大元素,並分析演算法的時間複雜性。

 

演算法描述:

基本的思路是利用劃分的思想減小問題的規模,但是按照一般的快速排序的演算法的思想,作為分界線的元素從第一個元素開始一直到最後一個元素,當遇到特殊情況時,每次只能分離一個元素,大大減少了演算法的效率,為了杜絕這種情況的出現,所以我們在演算法內引入規定範圍內的隨機數,以它作為獲取分界元素的依據,使得整個演算法的效率更加平穩,不會隨著資料樣本產生大幅度波動變化。

當減少的問題規模為1的時候,當前所剩下的唯一元素即為該問題的解。

 

程式碼:

package demo;
import java.util.Scanner;
public class MyCount {
	//尋找第五大元素
	public static int Search(int []array,int L,int R,int count) {
		//L是左邊界,R是右邊界,count是將要查詢第幾大元素
		if(L==R)//左右相等,排序完成,即也找到
			return array[L];
		int i = RParttition(array, L, R);
		int j = i-L+1;
		if(count<=j)
			return Search(array, L, i, count);
		else
			return Search(array, i+1, R, count-j);	
	}
	
	//隨機劃分
	public static int RParttition(int array[],int L,int R) {
		int i = L+(int)(Math.random()*((R-L)+0));//獲得一個範圍內的隨機數
		array[L] = (array[L]+array[i])-(array[i]=array[L]);
		return Partition(array,L,R);
	}
	
	//進行快速排序
	public static int Partition(int array[],int L,int R) {
		int i = L;
		int j = R+1;
		int x = array[L];
		while(true) {
			while(array[++i]<x&&i<R);
			while(array[--j]>x);
			if(i>=j)
				break;
			array[i] = array[i]+array[j] - (array[j]=array[i]);
		}
		array[L] = array[j];
		array[j] = x;
		return j;
	}
	
	public static void main(String[] args) {
		int n;
		System.out.println("請輸入你想輸入元素的個數:");
		Scanner sc = new Scanner(System.in);
		int input1 = sc.nextInt();
		n = input1;
		
		System.out.println("請輸入"+n+"個數字:");
		int a[] = new int[n];		
		for(int i=0;i<n;i++) {
			int input2 = sc.nextInt();
			a[i] = input2;
		}
		
		
		//呼叫函式
		System.out.println("第五個元素為:"+Search(a,0,n-1,5));
	}
}

 

相關文章