遞歸與分治策略(2)

轉載請聲明出處:http://blog.csdn.net/zhongkelee/article/details/45485943

一、分治法的基本思想

  分治法的適用條件

    分治法所能解決的問題一般具有以下幾個特徵:

    (1)該問題的規模縮小到一定程度就可以容易地解決。

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

    (3)利用該問題分解出的子問題的解可以合併爲該問題的解。

    (4)該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子問題。(對於有公共部分的子問題,用動態規劃較好,後續博客會講解)

    分治法的基本步驟

    devide-and-conquer(P)

    {

        if (|P| <= n0) adhoc(P);//解決小規模問題

        devide P into smaller sub-instances P1,P2,...,Pk;//分解問題

        for (i = 1; i <= k; i++)

            yi = devide-and-conquer(Pi);//遞歸地解各個子問題

        return merge(y1,y2,...,yk);//將各個子問題的解合併爲原問題的解

    }

    人們從大量實踐中發現,在用分治法設計算法時,最好使子問題的規模大致相同,即將一個問題分成大小相等的k個子問題的處理方法是行之有效的。這種使子問題規模大致相等的做法是出自一種平衡子問題的思想,它幾乎總是比子問題規模不等的做法要好。

    分治法的複雜性分析

    分治法將規模爲n的問題分成k個規模爲n/m的子問題去解。設分解閥值n0=1,且adhoc解規模爲1的問題耗費1個單位時間;再設將原問題divide爲k個子問題和用merge將k個子問題的解合併爲原問題的解需用f(n)個單位時間。用T(n)表示該分治法解規模爲|P|=n的問題所需的計算時間,則有


    應用主定理求得方程的解。

    下面討論一些運用分治策略的實例。

二、二分搜索技術

    給定已按升序排好序的n個元素a[0:n-1],現要在這n個元素中找出以特定元素x。

    分析:

    1.該問題的規模縮小到一定的程度就可以容易地解決;

    2.該問題可以分解爲若干個規模較小的相同問題;

    3.分解出的子問題的解可以合併爲原問題的解;

    4.分解出的各個子問題是相互獨立的。

    無論是在前面還是後面查找x,其方法都和在a中查找x一樣,只不過是查找的規模縮小了。這就說明了此問題滿足分治法的第二個和第三個適用條件。很顯然此問題分解出的子問題相互獨立,即在a[i]的前面或後面查找x是獨立的子問題,因此滿足分治法的第四個適用條件。

    二分搜索算法實現:

#include <iostream>

using namespace std;

int BinarySearch(int arr[], int x, int left, int right){
    while(left <= right){
        int middle = (left + right)/2;
        if (arr[middle] == x)
            return middle;
        if (arr[middle] > x)
            right = middle - 1;
        else
            left = middle + 1;
    }
    return -1;
}

int main()
{
    int array[] = {0,1,2,3,4,5,6,7,8,9};

    cout << "0 in array position: " << BinarySearch(array,0,0,9) << endl;
    cout << "9 in array position: " << BinarySearch(array,9,0,9) << endl;
    cout << "2 in array position: " << BinarySearch(array,2,0,9) << endl;
    cout << "6 in array position: " << BinarySearch(array,6,0,9) << endl;
    cout << "10 in array position: " << BinarySearch(array,10,0,9) << endl;
    return 0;
}

運行結果:

算法複雜度分析:

    每執行一次算法的while循環,待搜索數組的大小減小一半。因此,在最壞情況下,while循環被執行了O(logn)次。循環體內運算需要O(1)時間,因此整個算法在最壞情況下的計算時間複雜性爲O(logn)。

 

 


發佈了50 篇原創文章 · 獲贊 137 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章