c++ 归并排序

每个人写的归并细节都不同,把归并的原理弄懂:

1.将归并排序拆分为3个部分,其中最核心的是归并,如下的merge函数(将两个有序的数组或容器归并后排序)

2.将一个数组,开始分为单个的元素两两一起归并,得到以2个元素为单位的有序数组(Mergepass)2中有条件,若有剩下没有按次行归并规则归并的,若满足条件在单独归并,若不满足条件,直接拷贝到target数组中

*************************************注意2中的情况,列如数组有11个元素,再完成单个元素后,为 2,2,2,2,2,1此时前面四个2可以继续归并,而后面的2,和1也可以一起归并,然而当数组元素为10个,同样的完成单个元素后,为2,2,2,2,2,最后一个2,没办法归并,直接拷贝到下面的数组中去***************************************************

3.重复2的步骤后,此时归并的有序数组长度变为4,再一直重复下去(MergeSort)

 

 

撸算法一时爽,一直撸一直爽。。。。。。。。。。。。。。。

#include <iostream>
#include <algorithm>
using namespace std;

template <class T>//归并(将两个有序的数组合并后排序)
void merge(T* list,T* targetlist,const int l,const int m,const int n)
{
    int i=l;
    int j=m+1;
    int target_i=l;
    for ( i ,j,target_i; i <=m && j<=n ; target_i++) {
        if(list[i]<=list[j])
        {
//            cout<<"i++ 执行一次"<<i<<" "<<list[i]<<endl;
            targetlist[target_i]=list[i];
            i++;
        }
        else
        {

//            cout<<"j++ 执行一次"<<j<<" "<<endl;
            targetlist[target_i]=list[j];
            j++;
        }
//        cout<<"i= "<<i<<endl;
//        cout<<"j= "<<j<<endl;
//        cout<<"target_i:"<<target_i<<endl;
    }

//    cout<<"m= "<<m<<"i= "<<i<<endl;
    copy(list+i,list+m+1,targetlist+target_i);
    copy(list+j,list+n+1,targetlist+target_i);
}



//迭代归并
template <class T> //
void Mergepass(T* list, T* targetlist, int n,int s)
{
    int i;
    for (i = 0; i+2*s-1 <=n ;i+=2*s ) {
        merge(list, targetlist, i, i + s - 1, i + 2 * s - 1);
    }
    if (i+s-1<n)
    {
        merge(list,targetlist,i,i+s-1,n);
    }
    else
    {
        copy(list+i,list+n+1,targetlist+i);
    }
}

//最终的归并排序
template <class T>
void MergeSort(T* list, int n)
{
    T* targetlist=new T[n];
    for (int i = 1; i <n ; i*=2) {
        Mergepass(list,targetlist,n-1,i);
        i*=2;
        Mergepass(targetlist,list,n-1,i);
    }
    delete[]targetlist;
}



int main() {
    int a[]={1,3,4,5,6,2,4,8,12,14,48};
    int num= sizeof(a)/ sizeof(int);
    MergeSort(a,num);
    for (int i = 0; i <num ; i++) {
        cout<<a[i]<<" ";

    }
    cout<<endl;



//    int b[11]={0};
//    merge(a,b,0,4,10);
//    for (int i = 0; i <11 ; i++) {
//        cout<< b[i]<<" ";
//    }
//    cout<<endl;
//
//    cout<<"-------------------------------------"<<endl;
//
//
//    Mergepass(a,b,10,1);
//    for (int i = 0; i <11 ; i++) {
//        cout<< b[i]<<" ";
//    }
//    cout<<endl;
//
//    cout<<"--------------------------------------------"<<endl;
//
//    Mergepass(b,a,10,2);
//    for (int i = 0; i <11 ; i++) {
//        cout<< a[i]<<" ";
//    }
//    cout<<endl;
//
//
//    cout<<"--------------------------------------------"<<endl;
//
//    Mergepass(a,b,10,4);
//    for (int i = 0; i <11 ; i++) {
//        cout<< b[i]<<" ";
//    }
//    cout<<endl;
//
//

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值