分治基本概念:
把一个任务分成形式和原任务相同,但规模更小的几个部分子任务,分别完成,或只需要选一部分完成。然后再处理完成后的这一个或几个部分的结果,实现整个任务的完成。
动态规划基本概念:
通常许多子问题非常相似,为此动态规划试图仅仅解决每个子问题一次,从而减少计算量,算出子问题的解之后,则将其记忆化存储。
归并排序的解题思路: 数组排序任务可以按如下步骤完成:
(1)把前一半排序
(2)把后一半排序
(3)把两半归并到一个新的有序数组,然后再拷贝回原数组,排序完成
类似这样的,可以用两个指针p1,p2分别指向两个数组的起始位置,在前面做题的时候也遇到过链表的,链表思想类似,然后比较,小的那个存入临时数组tmp且指针往后移,tmp的指针pb在存放数据之后也跟随往后移指向下一个空的存储位置,最后别忘了处理长度一样的情况,其中有一个数组已经走到了头,则把剩下的元素存入后面。
代码如下:
`#include using namespace std;
int a[10] = { 13,27,19,2,8,12,2,8,30,89 };
int b[10];
void Merge(int a[], int s, int m,int e, int tmp[]) // a待排序的数组 tmp存放结果的临时数组 sm为起点和终点下标
{ //将数组a的局部a[s,m]和a[m+1,e]合并到tmp,并保证tmp有序, //然后再拷贝回a[s,m]
int pb = 0; // tmp数组初始指针指向起始位置
int p1=s, p2=m+1; //分开比较的两个数组指针
while (p1 <= m && p2 <= e) {
if (a[p1] < a[p2])
tmp[pb++] = a[p1++]; // 小的存入并往后移 tmp数组存完也往后一个位置
else
tmp[pb++] = a[p2++];
}
//其中有一个已经走到了头
while (p1 <= m) //p2走完了 p1还没走完
tmp[pb++] = a[p1++]; //把后面剩下的存入tmp
while (p2 <= e)
tmp[pb++] = a[p2++];
//拷贝回a数组
for (int i = 0; i < (e - s) + 1; i++)
a[s + i] = tmp[i];
}
void MergeSort(int a[],int s,int e,int tmp[])
{ int m;
m = s + (e - s) / 2;
if (s < e)
{
MergeSort(a, s, m, tmp);
MergeSort(a, m + 1, e, tmp);
Merge(a, s, m, e, tmp);
}
} int main() {
int size = sizeof(a) / sizeof(int);
MergeSort(a, 0, size - 1, b);
for (int i = 0; i < size; i++)
{
cout << a[i] << ",";
}
cout <<endl;
return 0;
} `
时间复杂度为O(nlongn),当比较到数组中只剩下一个元素是算法终止,即
T(n/2^k), 也就是n/2^k=1时成立,具体推导如下: