C++语言实现归并排序

归并排序的表现形式有多种,最常见的当然是递归归并排序,这里不再赘述。我们主要来实现两种不常用的归并排序形式:非递归归并排序和原地归并排序。

非递归归并排序

void Merge(int num[], int size)//size表示长度,因此索引应该最大是size-1
{
    int len = 1;
    while(len <= size)
    {
        for(int i = 0; i <= size - len; i+=2*len)
        {
            int low = i,mid = i+len-1,high = i+2*len-1;
            if(high > size-1)
                high = size-1;
            merge_sort(num,low,mid,high);
        }
        len = len * 2;
    }
}

void merge_sort(int num[], int l, int m, int h)
{
    int temp[h-l+1];
    int temp_iter = 0;
    int lb = l;
    int rb = m + 1;
    while(lb <= m && rb <= h)
    {
        if(num[lb] < num[rb])
            temp[temp_iter++] = num[lb++];
        else
            temp[temp_iter++] = num[rb++];
    }
    while(lb <= m)
        temp[temp_iter++] = num[lb++];
    while(rb <= h)
        temp[temp_iter++] = num[rb++];
    for(int j = l,i=0; j <= h,i < h-l+1; i++,j++)
        num[j]=temp[i];
}

原地归并排序(关于理论知识,童鞋们可以在网上查找):

//原地归并排序
void swap(int &first,int &second)
{
    //交换数组中两数的值
    int temp;
    temp = first;
    first = second;
    second = temp;
}
void reverse(int a[],int begin,int end)
{
    //反转数组
    while(begin < end)
    {
        swap(a[begin++],a[end--]);
    }
}
void exchange(int a[],int begin,int mid,int end)
{
    //分别反转前段和后段,之后反转整体
    reverse(a,begin,mid);
    reverse(a,mid+1,end);
    reverse(a,begin,end);
}
void merge(int a[],int begin,int mid,int end) //mid是第一段的最后一个
{
    int i = begin;
    int j = mid + 1;
    while( i < j && j <= end)
    {
        while(i < j && a[i] <= a[j]) //前段中小于中间值的数,索引后移;
        {
            i++;
        }
        int old_j = j;
        while(j <= end && a[j] < a[i]) //后段中小于当前a[i]的数,索引后移
        {
            j++;
        }
        exchange(a,i,old_j-1,j-1);//两段数置换
        i += (j - old_j);//前段数的后半段,应该向后移动的位数
    }
}
void merge_sort(int a[],int begin,int end)
{
    if(begin < end) //递归的自上向下进行处理
    {
        int mid = begin + (end - begin)/2;
        merge_sort(a,begin,mid);
        merge_sort(a,mid+1,end);
        merge(a,begin,mid,end);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值