递归与分治策略(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)。

 

 


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值