小鲤的碎碎念
归并的思路是什么呢?
叫你让两个数按升序排序,好排吧?
不就是大的数放后面,小的数放前面吗?如果第一个数比第二个数大,就交换!
你可能不加思索就给出了答案。那么,我给你四个数呢?当然,你一眼就可以看出来,但是小鲤希望用计算机的思维来解决哦。
欸,之前不是把两个数给排好序了吗?我把四个数拆成两组数,一比较就排好序了。然后看一下,这两组数第一个数谁更小放前面,大的再比较······
没错啦,那么更大规模的数呢,是不是也是以此类推呢?
你已经理解了归并,但是怎么实现呢?
动图演示(来源于网络)
归并模板
#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,还有算法视频;然后,可以来给小鲤的文章挑错
题目:
/**
* 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;
}
本题完全套用模版,难度不大,所用就不做讲解了。
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形式
😎测试案例过大将不会通过,与变量内存限制有关。
如
今天的内容已经结束了>_<
如果我的文章对你有帮助,不要吝惜你的点赞,小鲤希望得到你的支持ლ(´ڡ`ლ)
求三连和关注!!!