记录一下归并排序的学习心得
使用了分治算法,分而治之,fft就是一个典型的例子。
把大问题分解成小问题,不但使得问题简化,而且效率也高出了很多,
归并排序采用分裂组合的方式,没分裂组合一次,小问题的解即可得出,下一次在此基础上在分裂组合。
举个例子吧,假设从大到小排序
对 1 4 3 2进行排序,
首先分裂它,变成小问题
1 4 和3 2
解决小问题
1<4
-
4 1(排序)
3 >2
-
3 2(排序)
现在得到结果 4 1 3 2
再组合(注意4 1和3 2 分别是两个小问题的结果)
4 >3
4在第一位
1<3
3在第二位
1<2
2在第三位
最后把剩下的数字一次放大后面
便完成了一次小问题的组合。
用图形表示如下
现在应该基本明白了归并排序的思想
对于跟多的数字的排序,同样将之分解为小问题,然后递归调用,到最后就变成了如上所示最简单的问题,2个数,而这也是结束递归的条件
合并代码如图所示,顺便说一下真正的排序好像也就发生在这里
voidmergeArr(int sourceArr[],int tempArr[],int start,int mid,int last)
{
int i=start,j=mid+1,k=start;//分别取得两个小问题的端点,start-midmid+1->last
while(i != mid+1 && j != last+1) //其中的一个数组到尾了?
{
if(sourceArr[i]<sourceArr[j])//依次比较要合并的数组中的数字,按照大小放到tempArr中
tempArr[k++]=sourceArr[i++];
else
tempArr[k++]=sourceArr[j++];
}
while(i != mid+1)//把剩下的数字放到后面
tempArr[k++]=sourceArr[i++];
while(j != last+1)
tempArr[k++]=sourceArr[j++];
for(i=start;i!= last+1;i++)//复制到源数组
sourceArr[i]=tempArr[i];
}
voidmergeSort(int sourceArr[],int tempArr[],int start,int last)
{
int mid;
if(start<last)
{
mid=(start+last)/2;
mergeSort(sourceArr,tempArr,start,mid);//分裂成小问题
mergeSort(sourceArr,tempArr,mid+1,last);
mergeArr(sourceArr,tempArr,start,mid,last);//合并有序数组
}
}
加上main函数可测试
int main()
{
int a[]={1,3,2,12,4,3,23,45,12,45};
int b[11]={};
mergeSort(a,b,0,9);
for(int i=0;i<10;i++)
cout<<a[i]<<endl;
return 0;
}