归并排序----个人学习总结(C++)

代码呈现:

void merge_sort(int q[],int l,int r)
{
    if(l>=r) return;

    int mid = l + r >> 1;
    merge_sort(q,l,mid);
    merge_sort(q,mid+1,r);

    int k=0,i=l,j=mid+1;
    while(i<=mid && j<=r){
        if(q[i]<=q[j])
            temp[k++]=q[i++];
        else
            temp[k++]=q[j++];
    }
    while(i<=mid) temp[k++]=q[i++];
    while(j<=r) temp[k++]=q[j++];
    for(int i=l,j=0;i<=r;i++,j++){
        q[i]=temp[j];
    }
}

思想:

依旧是分治加递归,但与快排不同的是归并排序是先分到不能再分后排序归并,而快排是先根据基准点分成小和大的部分,再从部分里面继续分,相当于边分边排序了

1.先确定中点mid,将其分成左右两部分。

2.递归排序左右两个部分。

3.归并两个部分并排序(最重要的一步)

代码分析:

1.先将递归停止的判断条件写在前面,当左右边界重合相遇时停止。

2.写出数组中点位置mid,将左右两部分递归排序,在最里层的时候相当于数组中的单个元素,不需要比较返回上层,接下来是比较两个数以此类推等等。

3.最重要的一步,归并两个部分,此时我们需要借助一个额外的数组储存归并后的有序数组,所以引入一个变量k记录temp数组中的元素个数,然后采用双指针的算法,引入i,j分别指向两部分各自的第一个元素,将指向的两个元素比较,较小的元素写入temp数组并让指针前移,直到其中一个指针走到尽头。此时可能出现有一个指针没有遍历完的情况,于是接下来检查两个指针是否遍历完,如果没有就将后面的所有数据都写入temp数组。

4.最后将temp数组中的元素复制到q数组中

完整代码如下:

#include <iostream>

using namespace std;

const int N = 1e5+10;
int n;
int q[N],temp[N];

void merge_sort(int q[],int l,int r);
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&q[i]);
    }
    merge_sort(q,0,n-1);
    for(int j=0;j<n;j++){
        printf("%d ",q[j]);
    }
    return 0;
}
void merge_sort(int q[],int l,int r)
{
    if(l>=r) return;

    int mid = l + r >> 1;
    merge_sort(q,l,mid);
    merge_sort(q,mid+1,r);

    int k=0,i=l,j=mid+1;
    while(i<=mid && j<=r){
        if(q[i]<=q[j])
            temp[k++]=q[i++];
        else
            temp[k++]=q[j++];
    }
    while(i<=mid) temp[k++]=q[i++];
    while(j<=r) temp[k++]=q[j++];
    for(int i=l,j=0;i<=r;i++,j++){
        q[i]=temp[j];
    }
}

(用scanf是因为题目读入数据多的时候会比较快)

另外推荐一个数据结构可视化网站,可以看到归并排序的推理过程,十分清晰

Comparison Sorting Visualization

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值