分治算法的设计过程分为三个阶段:
Divide:问题分解,将整个问题划分成多个子问题
Conquery:递归求解各个子问题(递归调用设计的算法)
Combin:合并,合并子问题的解,形成原始问题的解。
基本思想:设两个有序的子序列(相当于输入序列)放在同一序列中相邻的位置上:array[low..m],array[m + 1..high],先将它们合并到一个局部的暂存序列 temp (相当于输出序列)中,待合并完成后将 temp 复制回 array[low..high]中,从而完成排序
#include <iostream>
using namespace std;
void merge(int* data ,int p,int q,int r)
{
int * left=NULL;//存储准备合并左边数组
int * right=NULL;//存储准备合并的右边数组
int n1,n2,i,j,k;
n1 = q-p+1;
n2 = r-q;
left=(int *)malloc(sizeof(int)*n1);//申请内存空间
right=(int * )malloc(sizeof(int)*n2);//申请内存空间
for(i=0;i<n1;i++)
{
left[i] = data[p+i];
}
for(i=0;i<n2;i++)
{
right[i]=data[q+i+1];
}
i=0;
j=0;
k=p;
//将两个排好序的数组合并
while(i<n1&&j<n2)
{
if(left[i]<right[j])
{
data[k++]= left[i++];
}
else
{
data[k++] = right[j++];
}
}
//合并完之后左边有剩余,复制进data
for(;i<n1;i++)
{
data[k++] = left[i];
}
//合并完之后右边有剩余,复制进data
for(;j<n2;j++)
{
data[k++] = right[j];
}
}
//使用分治算法的归并排序
void mergeSort(int* data,int p,int r)
{
int q;
if(p<r)
{
q = (int)((p+r)/2);//获得data数组分割点(中点)
mergeSort(data,p,q);//递归左边数组
mergeSort(data,p+1,r);//递归右边数组
merge(data,p,q,r);
}
}
int main(int argc, char const *argv[])
{
int a[8] = {10,30,50,80,46,98,75,45};
mergeSort(a,0,7);
for(int i=0;i<8;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
复杂性分析:
T(n) = 2T(n/2)+O(n)
T(n) = O(nlogn)