merge sort归并排序
思想:初始记录中有n个记录,想把它看作是n个长度为1的有序子序列,先做两两归并,得到n/2个归并项,重复上述过程,直到得到一个长度为n的有序序列。
递归,申请临时空间
void mergesort(int *arr,int size){
int *temp=(int *)malloc(size*sizeof(int));
if(!temp)
exit(OVERFLOW);
_mergesort(arr,0,size-1,temp); //调用分割排序算法
free(temp);
temp=NULL;
}
void _mergesort(int *arr,int left,int right,int *temp){
if(left>=right)
return; //判断数组是否需要排序
int mid=(left+right)/2; //进行分解
_mergesort(arr,left,mid,temp); //自归调用,分别对左半部分和右半部分进行排序
_mergesort(arr,mid+1,right,temp);
//合并
int begin1=left,end1=mid,begin2=mid+1,end2=right;
int i=begin1;
while(begin1<=end1 &&begin2<=end2){
if(arr[begin1]<arr[begin2]){
temp[i]=arr[begin1];
begin1++;}
else{
temp[i]=arr[begin2];
begin2++;}
i++;
}
while(begin1<=end1){ //循环继续,直到其中一个子数组的所有元素都被合并到temp中。
temp[i]=arr[begin1];
begin1++;
i++;}
while(begin2<=end2){
temp[i]=arr[begin2];
begin2++;
i++;}
for(i=left;i<=right;i++) //将temp数组复制回arr中
arr[i]=temp[i];
}
非递归调用的方法:
void Mergesort(int *arr,int size){
int *temp=(int*)malloc(size*sizeof(int));
if(!temp)
exit(overflow);
int gap=1; //与递归调用的区别,这里是用gap来存储每次分割的数组长度
while(gap<size){
int i=0;
for(i=0;i<=size;i+=2*gap){
int begin1=i,end1=i+gap-1;
int begin2=i+gap,end2=i+2*gap-1;
if(end1>size) //分情况讨论,当第一个数组越界
break;
if(begin2>size) //第二个数组全部越界
break;
if(end2>size) //第二个数组部分越界
end2=size-1;
int n=i;
while(begin1<=end1 && begin2<=end2){
if(arr[begin1]<arr[begin2]){
temp[n]=arr[begin1];
begin1++;}
else{
temp[n]=arr[begin2];
begin2++;}
n++;
}
while(begin1<=end1){
temp[n]=arr[begin1];
begin1++;
n++;
}
while(begin2<end2){
temp[n]=arr[begin2];
begin2++;
n++;
}
}
gap*=2;
}
free(temp);
temp=NULL;
}