分治法(歸併排序,X^n以及斐波那契數列)

分治法是解決問題的一種很好的思路,下面通過三種算法來了解分治法

public class DivideMethod {
	/**
	 * 歸併排序:歸併算法的中心是歸併兩個已經有序的數組,並且遞歸調用歸併操作。 優點和缺點:比簡單排序在速度上快很多;歸併排序會佔用雙倍的存儲空間。
	 * 效率:歸併排序的時間複雜度是 O(N*LogN);簡單排序的複雜度是O(N2)。 每一趟歸併的時間複雜度爲 O(n), 需要O(logn)次歸併
	 */
	public void mergeSort(int[] list) {
		int[] temp = new int[list.length];// 臨時數組
		divideMergeSort(list, temp, 0, list.length - 1);
	}

	// 遞歸分割數據到基本單位
	private void divideMergeSort(int[] list, int[] temp, int low, int upper) {
		if (low == upper) {
			return;
		} else {
			int mid = (low + upper) / 2;
			divideMergeSort(list, temp, low, mid);
			divideMergeSort(list, temp, mid + 1, upper);
			merge(list, temp, low, mid + 1, upper);
		}
	}

	// 歸併操作將基本單位歸併成整個有序的數組
	private void merge(int[] list, int[] temp, int left, int right, int last) {
		int j = 0;
		int lowIndex = left;
		int mid = right - 1;
		int n = last - lowIndex + 1;
		while (left <= mid && right <= last) {
			if (list[left] < list[right]) {
				temp[j++] = list[left++];
			} else {
				temp[j++] = list[right++];
			}
		}
		while (left <= mid) {
			temp[j++] = list[left++];
		}
		while (right <= last) {
			temp[j++] = list[right++];
		}
		for (j = 0; j < n; j++) {
			list[lowIndex + j] = temp[j];
		}
	}

	
	
	/**
	 * x^n的分治法策略
	 * x^n通過分治法可以轉換爲x^(n/2)*x^(n/2) 這種裝換就會變成兩個x^(n/2)的問題,並且兩個問題是一樣的,所以我們只需要解決一個問題就可以了,
	 * 所以時間複雜度就會從O(n)變爲 O(LogN)
	 */
	public int devideXToN(int x,int n){
		if(n==0){
			return 1;
		}
		if(n==1){
			return x; 
		}else{
			if(n%2==1){
				return devideXToN(x, n / 2) * devideXToN(x, n / 2) * x;
			}else{
				return devideXToN(x, n / 2) * devideXToN(x, n / 2);  
				
			}
		}
	}
	
	
	/**
	 * 斐波那契數列是 
	 *  f(0)=0  n=0
	 *  f(1)=1  n=1
	 *  f(n-1)+f(n-2) n>1
	 *  
	 *  如果採用遞歸求數列,有很多數字需要重複計算多次,採用分治法可以避免重複計算,
	 *  使計算的時間複雜段由指數級變爲線性的O(n)
	 * @param n
	 */
	public int fibonacci(int n){
		int rs = 1;
		int f1=1;
		int f2=1;
		if(n<2){
			return 1;
		}
		//通過保存中間結果的方法可以避免多次的重複計算
		for(int i=2;i<n;i++){
			rs = f1+f2;
			f1=f2;
			f2=rs;
		}
		return rs;
	}
	
	
}




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