分治就是將問題的乙個例項劃分為兩個或更多個較小的例項(這些較小的例項通常也是原問題的例項),一直持續劃分例項,直至問題規模小到可以輕鬆獲得答案為止。實際上這也可以說是一種遞迴的思想。
在包含size個元素的、從小到大排序的int陣列a裡查詢元素p,如果找到,則返回元素下標,如果找不到,則返回-1。
二分查詢函式非遞迴版本:
int binarysearch(int a,int size,int p)
void quicksort(int a,int s,int e)
//處理完後, a[i] = k
quicksort(a,s,i-1);
quicksort(a,i+1,e);
}
例題:輸出前m大的數
描述:給定乙個陣列包含n個元素,統計前m大的數並且把這m個數從大到小輸出。
輸入第一行包含乙個整數n,表示陣列的大小。 n < 100000。
第二行包含n個整數,表示陣列的元素,整數之間以乙個空格分開。每個整數的絕對值不超過100000000。
第三行包含乙個整數m。 m < n。
輸出從大到小輸出前m大的數,每個數一行。
解法一:排序後再輸出,複雜度 o(nlogn)
解法二:用分治處理: 複雜度 o(n+mlogm)
思路:把前m大的都弄到陣列最右邊,然後對這最右邊m個元素排序,再輸出
關鍵 : o(n)時間內實現把前m大的都弄到陣列最右邊
引入操作 arrangeright(k): 把陣列(或陣列的一部分)前k大的都弄到最右邊
如何將前k大的都弄到最右邊
1)設key=a[0], 將key挪到適當位置,使得比key小的元素都在
key左邊,比key大的元素都在key右邊(線性時間完成)
2) 選擇陣列的前部或後部再進行 arrangeright操作
例題:快速冪
非遞迴實現:
int pow(int a,int b)
return result;
}
遞迴實現:
int pow(int a,int b)
else
}
不應使用分治方法的情況:
乙個規模為n的例項被劃分成兩個或多個例項,而每個例項的複雜度仍然幾乎為n
乙個規模為n的例項被劃分為差不多n個規模為n/c的例項(c為常數)
比如很多書都會舉的斐波那契數列,如使用分治(遞迴)的方法將其分為f(n-1)與f(n-2)就會導致大量的重複計算,上述兩種情況的本質就是如此,只是導致的複雜度規模有所不同,此處不詳談。
而解決此類問題,一般會使用迴圈或者動態規劃。
基礎演算法排序之分治排序
寫在之前的話 對於博文的內容出現的本人觀點 博文中的內容有的摘自於演算法導論 的不當或者錯誤而對你造成困擾的話,你可以盡情的鄙視與吐槽,最好寫出你的觀點,本人定當虛心受教。分而治之,顧名思義也就是將原問題的規模分解成一系列規模小的子問題,演算法導論中是這麼說的 分治模式在每一層遞迴上都有三個步驟 分...
演算法基礎 分治法(基於Python)
有時候,你可能會遇到使用任何已知的演算法都無法解決的問題,這種時候,我們就可以試試分治法的思路。分治法的基本思想很簡單,顧名思義,就是將乙個大問題分解為若干個子問題,然後我們逐一地解決這些子問題,將所有子問題解決完畢,也就將整體的大問題解決完畢了。分治法的精髓 分 將問題分解為規模更小的子問題 治 ...
基礎演算法例題(遞迴 分治 )
遞迴 include include includeusing namespace std void comp int arr,int l,int r,int max1,int max2 else if r l 1 else else int main printf n comp a,0,n 1,m...