基础算法——归并排序(C++)

代码参考《算法笔记》但稍有改动,使用语言C++。

#include <iostream>

using namespace std;

/**归并排序**/


//递归实现
const int maxn=100;
//将数组A的[L1,R1]和[L2,R2]区间合并为有序区间(L2即R1+1)
void _merge(int A[],int L1,int R1,int L2,int R2)
{
    int temp[maxn];    //用于临时存放合并排序后的数组
    int ptr_left=L1,ptr_right=L2,ptr_tmp=0;
    while(ptr_left<=R1&&ptr_right<=R2)
    {
        if(A[ptr_left]<=A[ptr_right])
            temp[ptr_tmp++]=A[ptr_left++];
        else
            temp[ptr_tmp++]=A[ptr_right++];
    }
    while(ptr_left<=R1)
        temp[ptr_tmp++]=A[ptr_left++];
    while(ptr_right<=R2)
        temp[ptr_tmp++]=A[ptr_right++];
    //将已排序合并的临时数组复制到A中
    for(int i=0;i<ptr_tmp;i++)
        A[L1+i]=temp[i];
}
//将数组A当前区间[left,right]进行归并排序(主排序函数)
void mergeSort_1(int A[],int left,int right)
{
    if(left==right)   //需要进行排序的数组范围内只有一个数据,不需排序
        return;
    int mid=left+(right-left)/2;
    mergeSort_1(A,left,mid);
    mergeSort_1(A,mid+1,right);
    _merge(A,left,mid,mid+1,right);     //将左区间和右区间进行排序合并
}



//非递归实现
//令步长step初值为2,将数组中每step个元素为一组进行内部排序,再令step*2,重复操作
//直到step/2超过元素个数n(step/2==n为边界条件,此时左区间为整个数组,右区间为空,即将整个数组进行合并)
void mergeSort_2(int A[],int left,int right)
{
    int n=(right-left)+1;               //元素个数
    for(int step=2;step/2<=n;step*=2)    //每step个元素为一组进行内部排序合并
    {
        for(int i=left;i<=right;i+=step)       //i为每一小组的开头元素下标地址
        {
            int mid=i+step/2-1;
            if(mid+1<=right)          //判断小组是否只有一个元素,即右区间是否为空,为空则不用归并
                _merge(A,i,mid,mid+1,min(i+step-1,right));    //min(i+step-1,n)是为了防止右区间的右边界超出边界
        }

    }
}


int main()
{
    int A[9]={5,3,7,5,10,2,7,6,8};
    mergeSort_1(A,0,8);
    //输出测试
    for(int i=0;i<9;i++)
        cout<<A[i]<<" ";
    cout<<endl;

    int B[9]={5,3,7,5,10,2,7,6,8};
    mergeSort_2(B,0,8);
    //输出测试
    for(int i=0;i<9;i++)
        cout<<B[i]<<" ";
    cout<<endl;

    return 0;
}



 

对于非递归的合并排序,代码中的排序过程如下图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

音无八重

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值