第十章(10).归并排序(非递归)

#include <iostream>
using namespace std ;
//归并排序(Merging Sort) : 将两个或两个以上的有序表组成一个新的有序表.
//2-路归并排序中的核心操作是将一堆数组中前后相邻的两个有序序列归并为一个有序序列(此程序为非递归形式实现)

#define  MAXSIZE  20     //存储元素的顺序表的最大长度
typedef  int   KeyType ;   //关键字类型
typedef  int   InfoType ;   //其他数据项类型

typedef  struct {
 KeyType key ;
 InfoType otherinfor ;     //其他数据项
} RcdType ;

typedef  struct {
 RcdType r[ MAXSIZE + 1 ] ;    //r[0]闲置或用作哨兵单元
 int  length ;      //顺序表长度
} SqList ;         //顺序表类型

void InPut( SqList &L )
{
 int value = 0 ;
 int i = 1 ;
 while( i < ( MAXSIZE + 1 ) )
 {
  cin >> value ;
  if( value == -1 )     //以-1为结束符
   break ;
  L.r[ i ++ ].key = value ;
 }
 L.length = i - 1 ;
}

void OutPut( SqList L )
{
 for( int i = 1 ; i < L.length + 1 ; ++ i )
 {
  cout << L.r[ i ].key << ' ' ;
 }
 cout << endl ;
}

void Merge( RcdType SR[] , RcdType TR[] , int i , int m , int n )
{ //将有序的SR[i...m]和SR[m+1...n]归并为有序的TR[i..n]
 int j = 0 , k = 0 ;
 
 if( !SR || i < 0 || m < 0 || n < 0 )
  return ;
 for( j = m + 1 , k = i ; i < m + 1 && j < n + 1 ; ++ k )//将SR中记录由小到大地并入TR.
 {
  if( SR[ i ].key <= SR[ j ].key )
   TR[ k ] = SR[ i ++ ] ;
  else
   TR[ k ] = SR[ j ++ ] ;
 }
 
 while( i < m + 1 )
  TR[ k ++ ] = SR[ i ++ ] ;
 while( j < n + 1 )
  TR[ k ++ ] = SR[ j ++ ] ;
}

//合并元素个数为s的相邻数据(即要合并的两部分的总数据为2*s),n为总数据个数
void MSort( RcdType SR[] , RcdType TR[] , int s ,int n )
{
 int j = 1 ;
 
 while( j <= n - 2 * s + 1 )    //一组一组地进行归并(要进行一次合并,则至少要有(2*s)个元素,所以合并的起始位置最多只能为(n-2*s+1))
 {
  Merge( SR , TR , j , j + s - 1 , j + 2 * s -1 ) ; // (j + 2 * s - 1) - j + 1 = 2 * s (个元素)
  j += 2 * s ;      //一次性要合并s个元素,所以下一次合并的其实位置为j += 2 * s(如上所述)
 }
 
 //剩下的元素个数大于s小于2*s时,对这段用Merge
 //剩下的元素个数小于s时(即n<s),直接从SR复制到TR中去
 if( j + s < n + 1 )
  Merge( SR , TR , j , j + s - 1 , n ) ;
 else
 {
  while( j < n + 1 )
   TR[ j ] = SR[ j ++ ] ;   //"TR[ j ++ ] = SR[ j ++ ]" is a crazy error!  可以用for循环来消除这个错误隐患.
 }
}

void MergeSort( RcdType SR[] , int n )  //n为元素个数
{
 RcdType *TR = new RcdType[ n + 1 ] ; //在SqList数据结构中,第0号位置空置,所以需要n+1个空间.
 int step = 1 ;
 
 while( step < n )
 {
  MSort( SR , TR , step , n ) ;  //#1
  step += step ;
  MSort( TR , SR , step , n ) ;  //作用1:和#1轮替执行,保证源数据是被部分归并过的;
  step += step ;      //作用2:在归并完成后再调用一次,把最终归并结果copy到A数组中。其实是调用了MSort里最后的while循环。(如果为偶数次归并,则刚好归并完全。如果为奇数次归并,则最后一遍则是赋值. It's amazing!)
 }
 delete []TR ; 
}

int main( )
{
 SqList L ;

 InPut( L ) ;
 MergeSort( L.r , L.length ) ;
 OutPut( L ) ;

 return 0 ;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值