1. 程式人生 > >演算法05:二分搜尋演算法——分治法Part1

演算法05:二分搜尋演算法——分治法Part1

摘自網路:

分治法的設計思想是,將一個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。

分治法所能解決的問題一般具有以下幾個特徵:
1.該問題的規模縮小因為問題的計算複雜性一般是隨著問題規模的增加

2.該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質

3.利用該問題分解出的子問題的解可以合併為該問題的解;

     (如果具備了前兩條特徵,而不具備第三條特徵,則可以考慮貪心演算法或動態規劃)

4.該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子問題。    

     (如果各子問題是不獨立的,則分治法要做許多不必要的工作,重複地解公共的子問題,此時雖然也可用分治法,                但一般用動態規劃較好)

典型例子:

(1)二分搜尋技術; 
(2)大整數乘法;
(3)Strassen矩陣乘法;
(4)棋盤覆蓋;
(5)合併排序和快速排序;
(6)線性時間選擇;
(7)最接近點對問題;
(8)迴圈賽日程表。

(1)二分搜尋

給定已按升序排好序的n個元素a[0:n-1],現要在這n個元素中找出一特定元素x。二分搜尋很容易理解,這裡直接給出演算法程式碼

非遞迴演算法:

template<class Type> 
int BinarySearch(Type a[], const Type& x, int l, int r)
{
     while (r >= l){ 
        int m = (l+r)/2;
        if (x == a[m]) return m;
        if (x < a[m]) r = m-1; else l = m+1;
        }
    return -1;
} 
遞迴演算法:
template <class T>
int BinarySearch(T A[], T v, int l, int r)
{
    int j;

    if( l > r && v!=A[l])
      return -1;

   j=(r+l)/2;
   if( v == A[j])
      return j;
   else if (v < A[j])
      return BinarySearch(A,v,l,j-1);
   else
      return BinarySearch(A,v,j+1,r);
}