排序笔记-归并排序

一、 10大排序算法

在这里插入图片描述
在这里插入图片描述

二、归并排序原理图:

在这里插入图片描述

三、归并排序代码的递归实现

图1
图1

需要注意的地方
1.Merge函数为什么要传入这些参数呢?
想一下,抛开归并,你要合并两个肩并肩的数组要怎么做呢,要知道两个数组的起点和终点,通过下面三个参数可以算出来这两个数组的起点和终点(如上图,图1所示)
左边部分的起点和终点分别为 LeftRightLeft-1
右边部分的起点和终点分别为 RightLeft 和 RightEnd

void Merge(int a[],int tmp[],int left,int rightLeft,int rightEnd){

    int leftEnd=rightLeft-1;
    int length=rightEnd-left+1;
    int i=left;

    while((left<=leftEnd)&&(rightLeft<=rightEnd)){
        if(a[left]<=a[rightLeft]){
            tmp[i++]=a[left++];
        } else{
            tmp[i++]=a[rightLeft++];
        }
    }
    while(left<=leftEnd){//右边全部导入tmp,左边还有剩余
        tmp[i++]=a[left++];
    }
    while(rightLeft<=rightEnd){
        tmp[i++]=a[rightLeft++];
    }
    //再将tmp倒回到a中
    for(int i=0;i<length;i++,rightEnd--){
        a[rightEnd]=tmp[rightEnd];
    }

}

递归的方法还是很好理解的,重点强调一定要先理解递归排序的原理,最好结合图进行记忆
void MSort(int a[],int tmp[],int left,int right){
    if(left>=right){
        return;
    }
    int mid= (left+right)/2;
    MSort(a,tmp,left,mid);
    MSort(a,tmp,mid+1,right);
    Merge(a,tmp,left,mid+1,right);
    Dump(a,20,1);

}

2、为什么tmp这个临时数组要先申请,并随参数一直带着呢?明明只是在merge函数里才用到。
原因:
如果在merge函数里申请,就会不停的申请释放空间,效率低。
在这里插入图片描述
在外面申请的话只需要申请、释放一次即可
在这里插入图片描述

void MergeSort(int a[],int size){
    if(size<=1) {
        printf("Too few elements");
        return;
    }
    int *tmp =(int*)malloc(size* sizeof(int));
    if(nullptr==tmp){
        printf("malloc memery error");
        return;
    }
    else{
        MSort(a,tmp,0,size-1);
        free(tmp);

    }
}
//测试
void Dump(int a[],int size,int times){
    for(int i=0;i<size;++i){
        if(i==0){
            printf("sort %dth: ",times);
        }
        printf("%d ",a[i]);
    }
    printf("\r\n");
}

int main() {
    int a[20]={1,6,3,5,2,0,4,9,7,8,30,11,23,56,78,89,33,67,43,22};
    Dump(a,20,0);
    MergeSort(a,20);
    return 0;
}

归并排序的递归实现需要因为递归算法本身的限制,所以效率不高,归并算法还可以用非递归的形式来实现。

四、非递归的归并算法(待补充)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值