归并排序

今天遇到了leetcode的一道需要使用到归并排序的问题,然后开始自己学一下归并排序,写一下总结
就不说一些废话了,先了解一点,整个归并排序用到的就是递归的思想,所以在这边说一下那句话

递归就是一个遍历的思想,说实在,现在还不是太明白递归,等慢慢搞明白了,再写一下总结吧

void mysort(vector<int>&nums){
    vector<int> temp = vector<int>(nums.size());
    //在这边定义一个数组,就可以避免在递归里面去重复定义了
    mysort(nums,0,nums.size()-1,temp);
}

在C++这边,定义了两个mysort(),为了避免我们在递归里面去重复第建立数组,所以我们这边先进行定义,并且去调用我们实际上的mysort,也就是第二个mysort(),如下

void mysort(vector<int>&nums,int left ,int right,vector<int>&temp){
    if(left >=right){
        return ;
    }else {
        int mid = (left+right)/2;
        mysort(nums,left,mid,temp);//遍历我们左半边的数组
        mysort(nums,mid+1,right,temp);//遍历我们右半边的数组
        mymerge(nums,left,mid,right,temp);
    }
}

代码是不是特别简单呢?嘿嘿,我们只需要递归的思想,利用二分法,将数组分成两半,一直往下分,分出一个个的单体,然后再把这些单体合并起来,就可以获得我们最终的结果。
引用自https://www.cnblogs.com/chengxiao/p/6194356.html

引用自https://www.cnblogs.com/chengxiao/p/6194356.html

所以我们的merge函数就是再进行下面的那个合并的步骤,也就是在进行我们的回溯

void mymerge(vector<int>&nums,int left,int mid,int right,vector<int> temp){
    int i = left;
    int j = mid+1;
    int t =0;
    while(i<=mid&&j<=right){
        if(nums[i]<=nums[j]){
            temp[t++] = nums[i++];//这边的话,对于这个t++,嘿嘿,挺好玩的
        }else{
            temp[t++] = nums[j++];//这个也是
        }
    }
    while(i<=mid){
        temp[t++] = nums[i++];
    }
    while(j<=right){
        temp[t++] = nums[j++];
    }
    t = 0;
    //将temp中的元素全部拷贝到原数组中
    while(left <= right){
        nums[left++] = temp[t++];
    }
}

上面的代码就是合并两个有序的数组,就这个简单,所以归并排序特别的简单,嘿嘿,好好加油💪,问我为什么写得这么简单,因为我不知道怎么讲了,递归这东西,深入进去不好理解,随缘吧,先当个笔记,以后回来填坑。
完整的代码如下

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
void mymerge(vector<int>&nums,int left,int mid,int right,vector<int> temp){
    int i = left;
    int j = mid+1;
    int t =0;
    while(i<=mid&&j<=right){
        if(nums[i]<=nums[j]){
            temp[t++] = nums[i++];
        }else{
            temp[t++] = nums[j++];
        }
    }
    while(i<=mid){
        temp[t++] = nums[i++];
    }
    while(j<=right){
        temp[t++] = nums[j++];
    }
    t = 0;
    //将temp中的元素全部拷贝到原数组中
    while(left <= right){
        nums[left++] = temp[t++];
    }
}
void mysort(vector<int>&nums,int left ,int right,vector<int>&temp){
    if(left >=right){
        return ;
    }else {
        int mid = (left+right)/2;
        mysort(nums,left,mid,temp);
        mysort(nums,mid+1,right,temp);
        mymerge(nums,left,mid,right,temp);
    }
}
void mysort(vector<int>&nums){
    vector<int> temp = vector<int>(nums.size());
    mysort(nums,0,nums.size()-1,temp);
}
int main(){
    vector<int > number ={1,3,2,3,1,5,7,8,4};
    mysort(number);
    for(const auto x:number){
        cout<<x<<" ";
    }
    return 0;
}

附上Leetcode的题目链接
翻转对
以及题解

void reversePairs(vector<int>&nums,int left,int right,vector<int>&temp,int &ans){
    if(left==right){
        return;
    }else{
        int mid = (left+right)/2;
        reversePairs(nums,left,mid,temp,ans);
        reversePairs(nums,mid+1,right,temp,ans);

        //统计下标对的数量
        int i = left;
        int j = mid+1;
        while(i<=mid){
            while (j<=right&&(long long)nums[i]>2*(long long)nums[j]) j++;
            ans+=(j-mid-1);
            i++;
        }

        i = left;
        j = mid+1;
        int t =0;
        while(i<=mid&&j<=right){
            if(nums[i]<nums[j]){
                temp[t++] = nums[i++];
            }else{
                temp[t++] = nums[j++];
            }
        }
        while(i<=mid){
            temp[t++] =nums[i++];
        }
        while(j<=right){
            temp[t++] = nums[j++];
        }
        t=0;
        while(left<=right){
            nums[left++] = temp[t++];
        }
    }
}
void reversePairs(vector<int>& nums) {
    vector<int> temp = vector<int>(nums.size());
    int ans=0;
    reversePairs(nums,0,nums.size()-1,temp,ans);
    cout<<ans;
}

主要逻辑代码

//统计下标对的数量
        int i = left;
        int j = mid+1;
        while(i<=mid){
            while (j<=right&&(long long)nums[i]>2*(long long)nums[j]) j++;
            ans+=(j-mid-1);
            i++;
        }

这边的内容是判断合并之前的有序数组的符合翻转的组数,就只有这个代码,所以递归的本质就是遍历
***

递归就是遍历


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值