关于排序算法之归并排序

   一、使用递归算法

         递归算法的实质不难。分而治之,然后不断合并,最后形成一个整体。具体可以参考下面的图。

        

        

         算法导论上采用的是递归算法。

        

 1 void SelectSort::Merge(int p,int q,int k)  //从0开始计数
 2 {
 3    
 4     int n1 = q-p+1;           //左端数组大小
 5     int n2 = k-q;             //右端数组大小
 6     int *L = new int[n1+1];     //开辟左端
 7     int *R = new int[n2+1];     //开辟右端
 8     for(int i=0;i<n1;i++)  L[i] = SelectArry[p+i];
 9     for(int j=0;j<n2;j++)  R[j] = SelectArry[q+1+j];
10     L[n1] = INT_MAX;            
11     R[n2] = INT_MAX;
12     int i=0;
13     int j=0;
14     for(int s = p; s <=k;s++)    //s一定要小于等于k(为了与最后一个数做比较)
15        {
16         if(L[i] <=R[j]) {SelectArry[s] = L[i];i++;}
17         else {SelectArry[s] = R[j];j++;}
18        }
19 
20 }

          这个算法设置了一个小技巧,就是在第10、11行在左右数组中最后一个空间(每个L[]数组和R[]数组空间大小都比实际数组大小大1)设置为最大值。这个设置在for循环

中,利用if语句,比较大小时,可以将L[]或R[]区间中未比较的剩余元素自动在SelectArry数组进行填充。

 

 1 void SelectSort::Merge_Sort(int p,int q)
 2 {
 3     if(p<q)
 4     {
 5         int r = (p+q)/2;
 6         Merge_Sort(p,r);
 7         Merge_Sort(r+1,q);
 8         Merge(p,r,q);
 9     }
10 }

         进行递归调用,先左后右,到达底层后,再从分治到归并!

  二、分治算法(非递归)

 1 void SelectSort::Merge2(int index)
 2 {
 3     int i1 = 0;
 4     int i2,j1,j2;
 5     int i,j;
 6     int k = 0 ;                  //用于ReplaceArry数组计数
 7     while(i1+index<=int(SelectArry.size())-1)
 8     {
 9        j1 = i1+index;            //第二个分组的起点
10        i2 = j1-1;                //第一个分组的终点 
11        j2 = (j1+index-1<=int(SelectArry.size())-1)? j1+index-1:SelectArry.size()-1;    //第二个分组的终点
12        for(i=i1,j=j1;i<=i2&&j<=j2;k++)                   //两个有序字数组合并
13        {
14            if(SelectArry[i]<SelectArry[j]) {ReplaceArry[k] =SelectArry[i]; i++;}
15            else {ReplaceArry[k] = SelectArry[j];j++;}
16        }
17        while(i<=i2)                       //子数组2已经归并完毕,将子数组1剩余的元素存放到数组ReplaceArry数组中
18        {
19            ReplaceArry[k++] = SelectArry[i++];
20        }
21        while(j<=j2)                       //子数组1已经归并完毕,将子数组2剩余的元素存放到数组ReplaceArry数组中
22        {
23            ReplaceArry[k++] = SelectArry[j++];
24        }
25       i1 = j2+1;
26     }
27     for(i = i1;i<SelectArry.size();i++)  ReplaceArry[k++] = SelectArry[i]; //将原始数组中只够一组的数据元素顺序存放到数组ReplaceArry数组中
28 }

   非递归算法中,index代表一个数组中的元素数量大小。ReplaceArry数组用于存放按间距大小一轮比较交换完之后的数组。

 

 1 void SelectSort::Merge_Sort2()
 2 {    
 3      int i,k=1;
 4      while(k<SelectArry.size())
 5      {
 6        Merge2(k);                           //调用归并函数
 7        for(i=0;i<SelectArry.size();i++)
 8            SelectArry[i] = ReplaceArry[i];  //将元素从临时数组ReplaceArry放回数组SelectArry;
 9        k = 2 * k;                           //归并长度加倍
10      }
11 }

    由于是用类来写的,SelectArry、ReplaceArry数组封装在类中,其中SelectArry、ReplaceArry数组的定义是vector<int>;

    转载请注明出处http://www.cnblogs.com/Su-30MKK/archive/2012/11/07/2759659.html

       

 

  

   

转载于:https://www.cnblogs.com/Su-30MKK/archive/2012/11/07/2759659.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值