赞
踩
#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 ;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。