算法学习2 - 分治

分治三步骤
分解:将原问题分解为若干个模块较小,相互独立,与原问题形式相同的子问题。
解决:把规模较小容易被解决的直接解,否则递归解各个子问题。
合并:将子问题的解合并为原问题的解。

参考
中国大学MOOC - 算法基础
话歪之地的博客

1 归并排序


数组排序任务可以如下完成:
1) 把前一半排序
2) 把后一半排序
3) 把两半归并到一个新的有序数组,然后再拷贝回原数组,排序完成。

// -------- 代码实现归并排序 ---------

#include<iostream>  
using namespace std;  

int a[10]={5,7,9,1,8,4,6,10,3,2}, b[10];  

//将数组a的局部a[s,m]和a[m+1,e]合并到temp,并保证temp有序,然后再拷贝回a[s,m]  
// 归并时间复杂度:O(e-m+1),即O(n)
void Merge(int a[], int s, int m, int e, int temp[]){  
    int pb=0;  // 指向临时数组
    int p1=s, p2=m+1;  // 分别指向前一半和后一半数组
    while(p1<=m && p2<=e){  
        if(a[p2] < a[p1])  
            temp[pb++] = a[p2++];  
        else  
            temp[pb++] = a[p1++];  
    }  
    while(p1<=m)  
        temp[pb++] = a[p1++];  
    while(p2<=e)  
        temp[pb++] = a[p2++];  
    for(int i=0; i<pb; i++){  
        a[s+i] = temp[i];  
    }  
}  
//对数组a,将a[s]到a[e]归并排序  
void MergeSort(int a[], int s, int e, int temp[]){  
    if(s < e){  
        int m = s +(e-s)/2;  
        MergeSort(a,s,m,temp);  // 前一半排序
        MergeSort(a,m+1,e,temp);// 后一半排序
        Merge(a,s,m,e,temp);    // 合并
    }  
}  
int main(){  
    int length = sizeof(a)/sizeof(int);  // 需要排序的元素个数
    MergeSort(a,0,length-1,b);  // 归并函数
    for(int i=0;i<length;i++)  
        cout<<a[i]<<' ';  
    return 0;  
}

归并排序的时间复杂度
对n个元素进行排序的时间

T(n)=2T(n2)+an=2(2T(n4)+an2)+an=4T(n4)+2an=4(2T(n8)+an4)+2an=8T(n8)+3an==2kT(n2k)+kan

一直做到 n2k=1 , 此时 ( k=log2n ),
T(n)=2kT(1)+kan=2k+kan=n+a(log2n)n
复杂度 O(nlogn)

2 快速排序


数组排序任务可以如下:
1)设k = a[0],将k挪到适当位置,使得比k小的元素都在k左边,比k大的元素都在k右边。(O(n)时间完成)
2)把k左边的部分快速排序
3)把k右边的部分快速排序


    #include<iostream>  
    using namespace std;  

    //对数组a,从a[s]到a[e]进行快排  
    void QuickSort(int a[], int s, int e){  
        if(s >= e) return;  
        int key = a[s];  
        int left = s, right = e;  
        while(left != right){  
            while(left<right && a[right]>=key)  //从右往左找到比key小的  
                right--;  
            a[left] = a[right];  
            while(left<right && a[left]<=key)   //从左到右找到比key大的  
                left++;  
            a[right] = a[left];  
        }  
        a[left] = key;                          //此时left和right相等  
        QuickSort(a,s,left-1);  
        QuickSort(a,left+1,e);  
    }  

    int main(){  
        int a[]={5,7,9,1,8,4,6,10,3,2};  
        int length = sizeof(a)/sizeof(int);  
        QuickSort(a,0,length-1);  
        for(int i=0;i<length;i++)  
            cout<<a[i]<<' ';  
        return 0;  
    }

3 棋盘覆盖

棋盘覆盖问题分析(附代码)


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值