C++数据结构 7 归并排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014183456/article/details/82965360

归并排序算法采用的是分治算法,即把两个(或两个以上)有序表合并成一个新的有序表,即把待排序的序列分成若干个子序列,每个子序列都是有序的,然后把有序子序列合并成整体有序序列,这个过程也称为2-路归并.一般来说,n个数据大致会分为logN层,每层执行merge的总复杂度为O(n), 所以总的复杂度为O(nlogn)。

归并排序包含不相邻元素的比较,但并不会直接交换。在合并两个已排序的数组时,如果遇到了相同的元素,只要保证前半部分数组优先于后半部分数组,相同元素的顺序就不会颠倒,所以归并排序属于稳定的排序算法。

归并排序算法虽然高效且稳定,但在处理过程中除了用于 保存输入数据的数组外,还要临时占用一部分的内存空间。

C++迭代法:

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

  /*归并排序:两两排序好的数进行重新组排,归并排序是建立在归并操作上的一种有效的排序算法,
  //该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
  //将已有序的子序列合并,得到完全有序的序列;
  //即先使每个子序列有序,再使子序列段间有序。
  若将两个有序表合并成一个有序表,称为二路归并。 */
template <class T>
void Merge(T *initList,T *mergList,const int l,const int m,const int n)
{//initList初始数组  mergList归并好的数组 , l是第一个数组的下标,m是第二个数组的下标,n是数组个数
  int i1,i2,result;
  for(i1=l,i2=m+1,result=l;(i1<=m )&& (i2<=n); result++)
  {
      //进行比较
      if(initList[i1]<=initList[i2])  //小的放进合并数组里面
      {
          mergList[result]=initList[i1];
          i1++;
      }
      else
      {
        mergList[result]=initList[i2];
        i2++;
      }
  }
  copy(initList+i1,initList+m+1,mergList+result);  //把剩下的直接拷贝到mergList里面
  copy(initList+i2,initList+n+1,mergList+result);
}
template <class T>
void MergPass(T *initList,T *resultList,const int n,const int s)//n为元素个数,s为数组循环次数
{//一个数合并成两个数,这个过程中s=1,依次类推s=2....
    int i;
    for(i=1;i<n-2*s+1;i+=2*s)//进行合并
      Merge(initList,resultList,i,i+s-1,i+2*s-1);
    if((i+s-1)<n)  //如果没有剩余的,就进行归并
      Merge(initList,resultList,i,i+s-1,n);
    else  //如果有剩余的,就把剩下的复制下来
     copy(initList+i,initList+n+1,resultList+i);
}
template<class T>
void MergeSort(T *a,const int n)  //进行归并 n为数组个数
{
    T *templist=new int[n+1];  //templist[0]不用
    for(int l=1;l<n;l*=2)   //l每次取值都是1,2,4,8...
    {
       MergPass(a,templist,n,l); //第一次归并
       l*=2;
       MergPass(templist,a,n,l); //循环使用数组a,不会资源浪费
    }
    delete []templist;  //删除临时变量
}
int main()
{
    //int a[]={0,23,47,81,95,7,14,39,55,62,74};
    int x[]={0,23,47,81,95,7,14,39,55,62,74};
    MergeSort(x,10);
    for(int i=1;i<11;i++)
    {
        cout<<x[i]<<" ";
    }
    cout<<endl;
    return 0;
}

C++递归法:

#include<iostream>
using namespace std;
template <class T>
void merge(T *a,int n,int left,int mid,int right)
{
    //int L[maxn/2+2],R[maxn/2+2];
    T *L=new T[n+1];
    T *R=new T[n+1];
    int n1=mid-left,n2=right-mid;
    for(int i=0;i<n1;i++)
        L[i]=a[left+i];
    for(int i=0;i<n2;i++)
        R[i]=a[mid+i];
    L[n1]=R[n2]=1000;    //这个数设置的比数组里面的任何数都要大。否则会出错
    int i=0,j=0;
    for(int k=left;k<right;k++)
    {
        if(L[i]<=R[j])
            a[k]=L[i++];
        else
            a[k]=R[j++];
    }
    delete []L;
    delete []R;
}
void mergesort(int a[],int n,int left,int right)
{
    if(left+1<right)
    {
        int mid=(left+right)/2;
        mergesort(a,n,left,mid);
        mergesort(a,n,mid,right);
        merge(a,n,left,mid,right);
    }
}
void Merge(int a[],const int n)
{
   mergesort(a,n,0,n);
}
int main()
{
   // int a[maxn],n;
  //  cin>>n;
  // for(int i=0;i<n;i++)
  //     cin>>a[i];
    int a[]={23,47,81,95,7,14,39,55,62,74,26};
    Merge(a,11);
    for(int i=0;i<11;i++)
    {
        if(i)
            cout<<" ";
        cout<<a[i];
    }
    cout<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u014183456/article/details/82965360