merge sort

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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值