归并排序 C++示例

算法思想描述:

要对一个数组排序,可以将它先分为两个子数组分别排序,最后将结果合并。

下面介绍两种排序:自顶向下的归并排序和自底向上的归并排序。

1:自顶向下的归并排序

对一个数组排序先将左子数组排序,右子数组排序,最后合并形成最后的有序的数组,要对左子数组进行排序,采用同样的方式分割数组······

以整数数组为例:

#include <iostream>
#include <math.h>
using namespace std;
const int Num=25;
int Mid[Num]={0};
void Merge(int* s,int low,int mid,int up)
{
        int a=low,b=mid+1;
        for(int i=low;i<=up;i++)
                Mid[i]=s[i];
        for(int i=low;i<=up;i++)
        {
                if(a>mid)
                        s[i]=Mid[b++];
                else if(b>up)
                        s[i]=Mid[a++];
                else if(Mid[a]<=Mid[b])
                        s[i]=Mid[a++];
                else s[i]=Mid[b++];
        }
}
int Sort(int* s,int low,int up)//归并排序
{
       if(up<=low)
                return 0;
       else
       {
               int mid=(low+up)/2;
               Sort(s,low,mid);
               Sort(s,mid+1,up);
               Merge(s,low,mid,up);
       }
}

int main()
{
        int array[Num];
        srand(7);//初始化随机数
        for(int i=0;i<Num;i++)//初始化数组0到100之间
        {
                array[i]=rand() % 101;
        }
        for(int i=0;i<Num;i++)//输出原数组
        {
                printf("%d ",array[i]);
        }

        Sort(array,0,Num-1);

        printf("\n");
        for(int i=0;i<Num;i++)
        {
                printf("%d ",array[i]);
        }
    return 0;
}

2:自底向上的归并排序(非递归)

先归并那些微型数组,然后再成对归并得到子数组。

#include <iostream>
#include <math.h>
using namespace std;
const int Num=25;
int Mid[Num]={0};
void Merge(int* s,int low,int mid,int up)
{
        int a=low,b=mid+1;
        for(int i=low;i<=up;i++)
                Mid[i]=s[i];
        for(int i=low;i<=up;i++)
        {
                if(a>mid)
                        s[i]=Mid[b++];
                else if(b>up)
                        s[i]=Mid[a++];
                else if(Mid[a]<=Mid[b])
                        s[i]=Mid[a++];
                else s[i]=Mid[b++];
        }
}
int Sort(int* s)//归并排序
{
       for(int i=1;i<Num;i=i+i)
       {
               for(int j=0;j<Num-i;j+=i+i)
                        Merge(s,j,j+i-1,(j+i+i-1)<(Num-1)?(j+i+i-1):(Num-1));
       }
}

int main()
{
        int array[Num];
        srand(7);//初始化随机数
        for(int i=0;i<Num;i++)//初始化数组0到100之间
        {
                array[i]=rand() % 101;
        }
        for(int i=0;i<Num;i++)//输出原数组
        {
                printf("%d ",array[i]);
        }

        Sort(array);

        printf("\n");
        for(int i=0;i<Num;i++)
        {
                printf("%d ",array[i]);
        }
    return 0;
}


一个规模为N的数组,归并排序所需时间和NlgN成正比。相对于其他排序算法已经很优了,但是辅助数组的使用额外空间和N成正比。

改进 :

1:对于小规模数组使用插入排序算法。

2:Merge时先判断如果array[mid]<=array[mid+1]则数组已经有序,不用Merge().

3:不将元素复制到辅助数组。(采用其他方式,此处不详细展开)


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值