小鲤算法之归并排序介绍

小鲤的碎碎念

归并的思路是什么呢?

叫你让两个数按升序排序,好排吧?

不就是大的数放后面,小的数放前面吗?如果第一个数比第二个数大,就交换!

你可能不加思索就给出了答案。那么,我给你四个数呢?当然,你一眼就可以看出来,但是小鲤希望用计算机的思维来解决哦。

欸,之前不是把两个数给排好序了吗?我把四个数拆成两组数,一比较就排好序了。然后看一下,这两组数第一个数谁更小放前面,大的再比较······

没错啦,那么更大规模的数呢,是不是也是以此类推呢?

你已经理解了归并,但是怎么实现呢?

动图演示(来源于网络)

归并模板

#include <stdio.h>
#include <malloc.h>
 
#define maxn 1000001

int a[maxn];

void Input(int n, int *a) {
    for(int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
}

void Output(int n, int *a) {
    for(int i = 0; i < n; ++i) {
        if(i)
            printf(" ");
        printf("%d", a[i]);
    }
    puts("");
}

void MergeSort(int *nums, int l, int r) {
    int i, mid, p, lp, rp;
    int *tmp = (int *)malloc( (r-l+1) * sizeof(int) );    // (1)  
    if(l >= r) {
        return ;                                          // (2) 
    }
    mid = (l + r) >> 1;                                   // (3) 
    MergeSort(nums, l, mid);                              // (4) 
    MergeSort(nums, mid+1, r);                            // (5) 
    p = 0;                                                // (6) 
    lp = l, rp = mid+1;                                   // (7) 
    while(lp <= mid || rp <= r) {                         // (8) 
        if(lp > mid) {
            tmp[p++] = nums[rp++];                        // (9) 
        }else if(rp > r) {
            tmp[p++] = nums[lp++];                        // (10) 
        }else {
            if(nums[lp] <= nums[rp]) {                    // (11) 
                tmp[p++] = nums[lp++];
            }else {
                tmp[p++] = nums[rp++];
            }
        }
    }
    for(i = 0; i < r-l+1; ++i) {
        nums[l+i] = tmp[i];                               // (12) 
    } 
    free(tmp);                                            // (13) 
}

int main() {
    int n;
    while(scanf("%d", &n) != EOF) {
        Input(n, a);
        MergeSort(a, 0, n-1);
        Output(n, a);
    }
    return 0;
} 

代码来自大神英雄哪里出来,之《算法零基础100讲》(第36讲) 排序进阶 - 归并排序。

代码解释

(简化版附上我个人理解,详细请看大神博客)

主要讲解整体思路,这样看注释更容易理解;

首先,我们申请了一个内存空间,用来临时存放归并后数组;

然后,我们先开始递归分组(直到每组只有两个元素),对两个数的排序比较大小即可;

接着,我们开始归并,注意,此时的每一组数已经排好序。

考虑如果左边数组已经全部归并完,那么右边数组依此填入。右边情况同。

重置到原先的数组,然后释放空间。

over!

顺便安利一波:

学习算法的捷径:关注英雄哪里出来,参加万人千题社区,里面有大牛常驻,还有各种学习渠道;

刷题累了,可以看看英雄哪里出来的个人空间_哔哩哔哩_Bilibili,里面有激情澎湃的Bgm,还有算法视频;然后,可以来给小鲤的文章挑错

题目:

912. 排序数组

 



/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 void mergesort(int *nums,int l,int r){
   int i,mid,p,lp,rp;
   int *tmp =(int*)malloc((r-l+1)*sizeof(int));
   if(l>=r){
       return ;
   }
   mid=(l+r)>>1;
   mergesort(nums,l,mid);
   mergesort(nums,mid+1,r);
   p=0;
   lp=l,rp=mid+1;
   while(lp<=mid||rp<=r){
       if(lp>mid){
           tmp[p++] = nums[rp++];
       }else if(rp > r){
           tmp[p++] =nums[lp++];
       }else{
           if(nums[lp]<=nums[rp]){
               tmp[p++]=nums[lp++];
           }else{
               tmp[p++]=nums[rp++];
           }
       }
   }
   for(i=0;i<r-l+1;++i){
       nums[l+i]=tmp[i];
   }free(tmp);
 }
int* sortArray(int* nums, int numsSize, int* returnSize){
  mergesort(nums,0,numsSize-1);
  *returnSize=numsSize;
  return nums;
}

本题完全套用模版,难度不大,所用就不做讲解了。

164. 最大间距

 

 void mergesort(int *nums,int l,int r){
   int i,mid,p,lp,rp;
   int *tmp =(int*)malloc((r-l+1)*sizeof(int));
   if(l>=r){
       return ;
   }
   mid=(l+r)>>1;
   mergesort(nums,l,mid);
   mergesort(nums,mid+1,r);
   p=0;
   lp=l,rp=mid+1;
   while(lp<=mid||rp<=r){
       if(lp>mid){
           tmp[p++] = nums[rp++];
       }else if(rp > r){
           tmp[p++] =nums[lp++];
       }else{
           if(nums[lp]<=nums[rp]){
               tmp[p++]=nums[lp++];
           }else{
               tmp[p++]=nums[rp++];
           }
       }
   }
   for(i=0;i<r-l+1;++i){
       nums[l+i]=tmp[i];
   }free(tmp);
 }
int maximumGap(int* nums, int numsSize){
  
  if(numsSize<2){
      return 0;
  }else{
      mergesort(nums,0,numsSize-1);
      int max=0;
      for(int i=0;i<numsSize-1;i++){
           if(nums[i+1]-nums[i]-max>0){
               max=nums[i+1]-nums[i];
           }
    }return max;
  }
}

思路🤔为什么要写成nums[i+1]-nums[i]-max>0形式

😎测试案例过大将不会通过,与变量内存限制有关。

 

今天的内容已经结束了>_<

如果我的文章对你有帮助,不要吝惜你的点赞,小鲤希望得到你的支持ლ(´ڡ`ლ)

求三连和关注!!!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值