google了一下没找到像样的(实现太复杂,太低效),自己写一个发出来。以后还是要多贴些东西吧,不然博客很空! 下面的如果有可以改进的地方,表忘了告诉我。
自底向上的归并排序,举个例子吧还是:
现在要把下面的数组按递增顺序排列
9 8 7 6 5 4 3 2 1
step1:(len=1) 8 9 6 7 4 5 2 3 1
step2:(len=2) 6 7 8 9 2 3 4 5 1
step3:(len=4) 2 3 4 5 6 7 8 9 1
step4:(len=8) 1 2 3 4 5 6 7 8 9
每次归并分组都有空格隔开了的,其中len的意思是:把数组中长度为len的相邻的两段进行合并,当len大于数组长度是结束。
so easy! 应该容易理解吧. 具体实现见下面代码。
template <class T, class C>
void msort( T* table, const int& size, C cmp )
{
int flag = 0;
T* tmp = new T[size];
T* src;
T* dst;
int b1, b2, e1, e2, len, index, di;
for( len = 1; len <= size; len *= 2 ) //! O(logn)
{
if( flag % 2 == 0 ) src = table, dst = tmp;
else src = tmp, dst = table;
for( index = 0; index < size; index += ( len<<1 ) ) //! O(n)
{
if( index + len > size )
{
for( di = index; di < size; di++ ) dst[di] = src[di];
break;
}
b1 = index, b2 = index + len, e1 = b1 + len, e2 = b2 + len, di = index;
if( e2 > size ) e2 = size;
while( b1 < e1 && b2 < e2 )
dst[di++] = cmp( src[b1] ,src[b2] ) ? src[b1++] : src[b2++];
while( b1 < e1 )
dst[di++] = src[b1++];
while( b2 < e2 )
dst[di++] = src[b2++];
}
flag++;
}
if( flag % 2 == 1 )
memcpy( table, dst, sizeof( int ) * size );
delete [] tmp;
}
test code:
bool cmp( const int& a, const int& b ) { return a < b; }
int main()
{
int hsize = 20;
int testa[20] = \
{ 17 , 92, 3, 88, 5, 6, 7, 8, 9, 40, 11, 12, 13, 14, 25, 16, 87, 18, 19, 20 };
msort( testa, hsize, cmp );
for( int i = 0; i < hsize; i++ )
std::cout<<testa[i] << " ";
std::cout<< "\n";
return 0;
}