归并算法得核心思路是:
1将一个序列一直对半分,直到序列得个数为1
2合并相邻得两个有序序列
实现得方式是采用递归得方式。具体实现如下:
void MergeSort(int* array,int length)
{
if(array != NULL && length > 0)
{
if(length == 1)
{
//递归结束条件
return;
}
else
{
//分
int boundaryIndex = length / 2;
//归并左边
MergeSort(array,boundaryIndex);
//归并右边
MergeSort(&array[boundaryIndex],length - boundaryIndex);
//合并左和右
int* tmpArray = new int[length];
int* leftArray = array;
int* rightArray = array + boundaryIndex;
int tmpCurIndex = 0; //始终指向待插入得位置
int i = 0;
int j = 0;
while(i < boundaryIndex && j < length - boundaryIndex)
{
if(leftArray[i] < rightArray[j])
{
tmpArray[tmpCurIndex] = leftArray[i];
i++;
}
else
{
tmpArray[tmpCurIndex] = rightArray[j];
j++;
}
tmpCurIndex++;
}
//拷贝剩余得到临时数组
while(i < boundaryIndex)
{
tmpArray[tmpCurIndex] = leftArray[i];
i++;
tmpCurIndex++;
}
while(j < length - boundaryIndex)
{
tmpArray[tmpCurIndex] = rightArray[j];
j++;
tmpCurIndex++;
}
for(int moveIndex = 0;moveIndex < length;moveIndex++)
{
array[moveIndex] = tmpArray[moveIndex];
}
delete[] tmpArray;
}
}
}
int main() {
int array[] = {12,31,1,21,11,3,56,14,89,10};
int length = sizeof(array) / sizeof(array[0]);
MergeSort(array,length);
std::for_each(array,array+length,[](int i){
std:: cout << i << " ";
});
std::cout << std::endl;
cout << "test\n";
return 0;
}
此处注意得点:
1 设置递归结束条件
2 要具有宏观上得思路,即 先MergeSoft(leftArray,leftlength),再MergeSoft(rightArray,rightlength),然后合并左右两边得数据到临时数据,最后将临时数组得内容拷贝回原来得数值。不要陷入具体的递归步骤。
归并算法得时间复杂度计算:
以最最糟糕得情况评估:
因为每次比较都会像临时数值tmp中加一个数,所以当tmp数组满了代表比较完了。所以每次比较次数如下:
每次分组情况: 1 2 4 8 … n/2 n (最后一个数一个组,n个数就有n组)
每组得个数: n n/2 n/4 n/8 … 1
所有组比较得次数:0 n n n … 0
理论上是log2n次
那么就可以粗略得看作是log2n个n
即 nLog2n 次比较操作
所以归并算法最糟糕得情况下时间复杂度:O(nlog2n)