排序算法复习之——内部排序算法之归并排序
归并排序
归并排序是将若干个已排序的文件合成一个有序的文件。
两路归并排序算法的思路:设两个有序的文件放在同一向量中相邻的位置上,即A[low…m]与A[m+1…high],先将它们合并到一个局部暂存向量Temp中,待合并完成后将Temp复制回A[low…high]中。
自顶向下归并排序步骤:设归并排序的当前区间是A[low…high]
(1) 分解:将当前区间一分为二,即求分割点
(2) 求解:递归这两个子区间A[low…mid] 和A[mid+1…high]进行归并排序。
(3) 组合:将已排好的两个子区间A[low…mid] 和A[mid+1…high]归并为一个有序的区间A[low…high]
(4) 递归的终点条件是:子区间长度为1
实现代码:
#include <iostream>
using namespace std;
//将分治的两端大小次序填入临时数组,最后把临时数组复制到原始数组中
//lPos到rPos-1为一端,rPos到rEnd为另外一端
void Merge(int a[],int tmp[],int lPos,int rPos,int rEnd)
{
int i,lEnd,NumElements,tmpPos;
lEnd = rPos-1;
tmpPos = lPos; //从左端开始
NumElements = rEnd-lPos+1; //数组长度
while (lPos<=lEnd && rPos<rEnd)
{
if (a[lPos]<=a[rPos])
tmp[tmpPos++] = a[lPos++];
else
tmp[tmpPos++] = a[rPos++];
}
//到这里,左端或者右端只能有一端还可能有剩余元素
while(lPos<=lEnd) //把左端剩余元素放入tmp
tmp[tmpPos++] = a[lPos++];
while(rPos<=rEnd) //把右端剩余元素放入tmp
tmp[tmpPos++] = a[rPos++];
for (i=0; i<NumElements; i++,rEnd--)
{
a[rEnd] = tmp[rEnd]; //把临时数组复制到原始数组
}
}
void msort(int a[],int tmp[],int low,int high)
{
if (low >= high)
return;
int middle = (low+high)/2; //计算分割点
msort(a,tmp,low,middle); //对子区间[low,middle]递归做归并排序
msort(a,tmp,(middle+1),high); //对子区间[(middle+1),high]递归做归并排序
Merge(a,tmp,low,(middle+1),high); //组合,把2个有序区合并为一个有序区
}
void merge_Sort(int a[],int len)
{
int *tmp = NULL;
tmp = new int[len]; //分配临时数组空间
if (tmp!=NULL)
{
msort(a,tmp,0,len-1); //调用mSort归并排序
delete[]tmp; //释放临时数组内存
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[8]={8,6,1,3,5,2,7,4};
merge_Sort(a,8);
system("pause");
return 0;
}
运行结果:
暂时没调出来,后续更正。
参考资料:《c++程序员手册 》 人民邮电出版社 张京、胡凌云