分治思想与应用

分治

分治算法就是分而治之。分治分治,分为两部分,

分:

划分子问题,讲一个问题划分成若干个独立的具有共性的子问题。

治:

求解每个子问题。

分解:

分解子问题的原则:

  1. 子问题与原问题性质相似。
  2. 子问题规模较小(有解)
  3. 合并:把每个子问题的解合并成原问题的解

适用场景

  1. 在一个较小规模上得到解
  2. 该问题上有最有子结构
  3. 每个子问题的解,可以合并为原问题的解

例题1:二分查找: (适合有序顺序表

给定一个升序有序数组,要求找到到值为key的元素的位置,若没有则返回-1。

#include "iostream"

using namespace std;

int halfSearch(int Data[], int low, int high, int key);

int main()
{
    int n[] = {1,2,3,4,5,6,7,8};
    int k;
    cout << "Please Input Key:";
    cin >> k;
    cout << halfSearch(n, 0, sizeof(n)/sizeof(n[0]), k);
    return 0;
}

//high = length
//递归
int halfSearch(int Data[], int low, int high, int key){
    int mid = (low + high) / 2;
    if (low <= high){
        if (Data[mid] < key)
            halfSearch(Data, mid + 1, high, key);
        else if (Data[mid] > key)
            halfSearch(Data, low, mid-1, key);
        else if (Data[mid] == key)
            return mid;
    }
    else
        return -1;
}

例题2:返回X的n次方

#include "iostream"

using namespace std;

int Power(int x, int n);

int main(int argc, char const *argv[])
{
    int x1, n1;
    cout << "Please Input x and n:";
    cin >> x1 >> n1;
    cout << "Power(x,n) is " << Power(x1,n1) << endl;
    return 0;
}

int Power(int x, int n){
    int result;
    if ( n == 1)
        return x;
    if ( n%2 == 0 )
        result = Power(x, n/2)*Power(x, n/2);
    else 
        result = Power(x, (n - 1)/2)*Power(x, (n+1)/2);
    return result;
}

例题3:归并排序 (二路归并)

给定一个无序顺序表,请使用分治思想,将其排序。

#include "iostream"
#include "string"
using namespace std;

void Marge_Sort(int a[], int low, int high, int *tmp);
void Print(int a[], int length);

int main(int argc, char const *argv[])
{
    int a1[] = {3,2,8,5,4,7,6,9};
    int *tmp, n;
    n = sizeof(a1)/sizeof(a1[0]);
    tmp = (int *)malloc(n*sizeof(a1[0]));
    Marge_Sort(a1, 0, n-1, tmp);
    free(tmp);
    Print(a1, n);

    return 0;
}

void Marge_Sort(int a[], int low, int high, int *tmp){
    int i, j, k;
    if (low < high){
        // 分:
        int mid = (low + high) / 2;
        Marge_Sort(a, low, mid, tmp);
        Marge_Sort(a, mid + 1, high, tmp);
        // 治:
        for (k = 0, i = low, j = mid + 1; i < mid + 1 && j < high + 1;){
            if (a[i] < a[j])
                tmp[k++] = a[i++];
            else
                tmp[k++] = a[j++];
        }
        while(i < mid+1)
            tmp[k++] = a[i++];
        while(j < high + 1)
            tmp[k++] = a[j++];
        memcpy((void*)(a + low), (void *)tmp, (high - low + 1)*sizeof(a[0]));
    }
    
}

void Print(int a[], int length){
    int i = 0;
    while (i < length)
        cout << a[i++] << "   ";
    cout << endl;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值