注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 获取当前页面路径,实现权..
 帮助

归并排序 c++实现


2007-04-09 23:48:39
 标签:c++   [推送到技术圈]

版权声明:原创作品,如需转载,请与作者联系。否则将追究法律责任。
1、   分析问题
对一个数组进行排序,可以将之分解为n个已经排序的子问题,然后进行合并就可以得到了原问题的解。我们可以用分治法来解着这个问题。
通过对问题的分析,这个问题的解题方法符合分治法的条件:
l      该问题的规模缩小到一定的程度就可以容易地解决;
l      该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质
l      利用该问题分解出的子问题的解可以合并为该问题的解;
l      该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
 
2、 根据问题分析,设计利用分治法解决问题的基本思路
     分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归的解这些子问题,然后将个子问题的解合并得到原问题的解。
    分治法的基本步骤
 divide-and-conquer(P)
  {
    if ( | P | <= n0) adhoc(P);   //解决小规模的问题
    divide P into smaller subinstances P1,P2,...,Pk//分解问题
    for (i=1,i<=k,i++)
      yi=divide-and-conquer(Pi);  //递归的解各子问题
    return merge(y1,...,yk);  //将各子问题的解合并为原问题的解
  }
 
3、 算法设计
在这个问题中主要用到三个基本算法:
1、  把大的问题分解成小的问题:MergeSort;
2、  把两个较小的子问题合并成一个较大的问题:Merge
3、  对已排序数组进行拷贝:Copy;
  具体算法(C++语言):
template <class Type >
void MergeSort(Type a[],int left,int right)
{
if(left<right){   //至少有2个元素
int i=(left+right)/2;  //取中点
MergeSort(a,left,i);
MergeSort(a,i+1,right);
Merge(a,b,left,i,right);  //合并到数组b
Copy(a,b,left,right);   //复制回数组a
}
}
Template <class Type >
void Merge(Type c[],Type d[],int left,int m,int right )
{
    int i=1eft,
        j=m+1;
        k=1eft;
    while((i<=m)&&(j<=right))
      if(c[i]<=c[j]) d[k++]=c[i++];
        else d[k++]=c[j++];
    while(j<=right)
          d[k++]=c[j++];
    while(i<=m)
       d[k++]=c[i++];
}
 
  template <class Type>
void Copy(Type a[],Type b[],int left,int right)
{
   int i=left,
   for(;i<=right;i++)
     a[i++]=b[j++];
}
4、 算法的时间复杂度和空间复杂度分析
时间复杂度分析:Merge Copy 内可完成,因此合并排序算法对n 个元素进行排序,在最坏的情况下所需的计算时间 满足:
解此递归方程可知 。由于排序问题的计算时间下界为 ,故合并排序算法是一个渐进最优算法。
空间复杂度分析:在排序过程中需要与排序数组等长的数组来存放数组拷贝,所以空间复杂度为: =
5、 算法实现
具体算法:
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
 
template <class Type>
/*  为了便于维护,现在把排序封装在类ArraySort
*/
class ArraySort
{
   private: int elem; //elem的值决定按升序还是降序
           int len; //排序数组的长度
           Type *b; //排序时用与交换的数组
         Type *a; //用来存放要排序的数组;
   public:
      void set(Type c[],int k); //接收要排序的数组及数组长度
       void Sort(); //进行排序
      void   MergeSort(int ,int );
       void Merge(int ,int ,int); //进行合并
      void Copy(int ,int); //复制一个数组到另一个数组
      void ArPrint(); //输出数组元素
      void ReturnCopy(Type c[]); //把已经排序数组返回给原数组
      ~ArraySort();
         ArraySort(int k=0){
             elem=k;
          len=0;
          a=NULL;
          b=NULL;
   }
};
      template<class Type>
     void ArraySort<Type>::set(Type c[],int k )
     {   int m;
        len=k;
          //len=c.length;
          a=new Type[len];
         b=new Type[len];
      if((a==NULL)||(b==NULL))
        {   cout<<"can't allocate more memory,terminating."<<endl;
               exit(1);
        }
      else{
             for(int i=0;i<len;i++)
                 a[i]=c[i];
        }
      cout<<" input the number 0 or 1:"<<endl;
      cout<<"0 min to max:"<<endl;
      cout<<"1 max to min"<<endl;
      cin>>m;
       if(m>=0&&m<=1)
             elem=m;
       else {
            cout<<"You input a illegal number!!";
              cout<<" input the number 0 or 1:"<<endl;
             cout<<"0 min to max:"<<endl;
             cout<<"1 max to min"<<endl;
       }
     }
     template <class Type>
     void ArraySort<Type>::Sort()
     {
        MergeSort(0,len-1);
     }
      template <class Type>
        void ArraySort<Type>::Merge(int left,int m,int right)
     {
        int i=left,
           j=m+1,
          k=left;
       if(elem==0){
      while((i<=m)&&(j<=right))
         if(a[i]<=a[j]) b[k++]=a[i++];
         else b[k++]=a[j++];
       }
       else{
          while((i<=m)&&(j<=right))
         if(a[i]>=a[j]) b[k++]=a[i++];
         else b[k++]=a[j++];
       }
      while(i<=m)
         b[k++]=a[i++];
      while(j<=right)
         b[k++]=a[j++];
     }
      template <class Type>
        void ArraySort<Type>::Copy(int left,int right)
     {
        for(int i=left;i<=right;i++)
          a[i]=b[i];
     }
      template <class Type>
        void ArraySort<Type>::ArPrint()
     {
       // int len=this.a.length;
        cout<<"The length of array is :"<<len<<endl;
        cout<<"The elements of array is :"<<endl;
        for(int i=0;i<len;i++)
           cout<<"  "<<a[i];
        if(i/5==0)
           cout<<endl;
     }
       template <class Type>
           void ArraySort<Type>::MergeSort(int left,int right)
        { 
           if(left<right){
              int i=(left+right)/2;
                MergeSort(left,i);
                MergeSort(i+1,right);
                Merge(left,i,right);
                Copy(left,right);
           }
        }
      template <class Type>
        void  ArraySort<Type>::ReturnCopy(Type c[])
     {
        for(int i=0;i<len;i++)
          c[i]=a[i];
     }
      template <class Type>
    ArraySort<Type>::~ArraySort()
     {
     delete a;
     delete b;
     }
void main()
{  //const int length=10;
   const int length=15;
    int i;
// int c[length]={12,2,4,3,56,54,76,82,8,5};
   int c[length]={1,9,3,4,6,78,15,34,56,0,74,14,10,21,49};
  ArraySort<int > as;
    as.set(c,length);
   cout<<"排序前的数组元素序列:"<<endl;
    for( i=0;i<length;i++)
            cout<<"  "<<c[i];
            cout<<endl;     
   as.Sort();
// as.ArPrint();
   as.ReturnCopy(c);
   //cout<<endl;
   cout<<"排序后的数组元素序列:"<<endl;
     for( i=0;i<length;i++)
       cout<<"  "<<c[i];
     cout<<endl;
}

本文出自 “我爱你” 博客,转载请与作者联系!







    文章评论
 
2007-04-10 08:47:11
不错的文章。。。这个程序能用C实现嘛?

2007-06-05 16:51:25
那请问,算法的时间复杂性的递归方程呢,怎么没有看到?还有那个最坏情况下的时间复杂性

2008-02-28 09:52:11
你的函数声明不规范,变量名不利于代码的可读性
值传递用的太多,好几处都是很大的数组做参数,影响程序的效率
而且在释放内存的时候没有释放干净
delete []a;
delete []b;

逻辑性不错,算法表达的很正确

 

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: