归并排序
归并操作的基本步骤如下:
1.申请两个与已经排序序列相同大小的空间,并将两个序列拷贝其中;
2.设定最初位置分别为两个已经拷贝排序序列的起始位置,比较两个序列元素的大小,依次选择相对小的元素放到原始序列;
3.重复2直到某一拷贝序列全部放入原始序列,将另一个序列剩下的所有元素直接复制到原始序列尾。
设归并排序的当前区间是R[low..high],分治法的三个步骤是:
1.分解:将当前区间一分为二,即求分裂点
2.求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;
3.组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。
递归的终结条件:子区间长度为1(一个记录自然有序)。
亲自实践如下
#include <iostream>
#define max( x , y ) ((x)>(y)?(x):(y))
#define len(r) (unsigned int)(sizeof(r)/sizeof(r[0]))
using namespace std;
//int* mergeList(int r1[],int len1,int r2[],int len2){
// int pointer1 = 0,pointer2 = 0,pointer3 = 0;
// int *merge_r = new int[len1+len2];
// while(pointer1 < len1 && pointer2 < len2){
// if(r1[pointer1] < r2[pointer2]){
// merge_r[pointer3] = r1[pointer1];
// pointer1++;
// pointer3++;
// }else{
// merge_r[pointer3] = r2[pointer2];
// pointer2++;
// pointer3++;
// }
// }
//
// if(pointer1 < len1){
// while(pointer1 < len1){
// merge_r[pointer3] = r1[pointer1];
// pointer3++;
// pointer1++;
// }
// }
// if(pointer2 < len2)
// {
// while(pointer2 < len2){
// merge_r[pointer3] = r2[pointer2];
// pointer3++;
// pointer2++;
// }
// }
// return merge_r;
//}
void mergelist(int r[],int start,int middle,int last){
//考虑左开右闭区间
int n1 = middle-start;
int n2 = last - middle;
int *l1 = new int[n1];
int *l2 = new int[n2];
for(int i = 0; i < n1; i ++)
l1[i] = r[start+i];
for(int i = 0; i < n2; i ++)
l2[i] = r[middle+i];
int p1=0,p2=0,p=start;
while(p1<n1&&p2<n2){
if(l1[p1] < l2[p2])
r[p++] = l1[p1++];
else
r[p++] = l2[p2++];
}
while(p1 < n1) r[p++] = l1[p1++];
while(p2 < n2) r[p++] = l2[p2++];
delete l1;
delete l2;
}
void mergeSort(int r[],int start,int last){
if(start < last - 1){
int middle = start + (last-start)/2;
mergeSort(r,start,middle);
mergeSort(r,middle,last);
mergelist(r,start,middle,last);
}
}
void print(int r[],int length){
for(int i = 0; i < length; i ++)
cout << r[i] << "\t";
cout << endl;
}
int main()
{
int r[] = {1,3,4,9,6,2,5,8,7,0};
mergeSort(r,0,len(r));
print(r,len(r));
return 0;
}

浙公网安备 33010602011771号