CLRS 8.3-4 :
说明如何在O(n)时间内,对0到n^2 - 1之间的n个整数进行排序。
算法思想:
1.把这n个数看成n进制数,那么每个数只有两位,因而循环只需两次
2.调用通用的基数排序(在这写着,留着以后用)
在此题中,我选择n = 15, 即数组中有15个数,依次为0, 3, 8, ..., 224,但是将顺序打乱了。
PS:在前一篇文章中,计数排序的总时间为O(k+n),在实践中,如果当k = O(n)时,我们常常采用计数排序,这时其运行时间为O(n).
在这里采用的是基数排序,在实践中,其排序时间为O(d*(n+k)),但很耗内存,有时甚至比快速排序更快,具体应用再看。
#include
<
iostream
>
#include < math.h >
using namespace std;
void radix_sort( int a[], const int d, const int length, int radix);
int getBit( int m, int i, int radix);
int pow2( int a, int b);
int main()
{
// 数组长度
const int LEN = 15 ;
int a[LEN] = { 35 , 48 , 0 , 8 , 15 , 80 , 99 , 3 , 24 , 168 , 195 , 224 , 63 , 120 , 143 };
// 多少位
const int d = 2 ;
// 基数
const int radix = 15 ;
// 在这调用的是通用的基数排序算法,可以任意改变基数radix,
// 但记得改变d,因为radix改变的话,数字的位数会改变,
// 最简单的是十进制改成二进制,位数激增
radix_sort(a, d, LEN, radix);
for ( int i = 0 ; i < LEN; i ++ )
cout << a[i] << endl;
}
void radix_sort( int a[], const int d, const int length, int radix)
{
// 存储a中每个元素的余数
int * remainder = new int [length];
// 统计余数(等同于计数排序中的c)
int * c = new int [radix];
// 保存排序之后的a
int * b = new int [length];
for ( int i = 0 ; i < radix; i ++ )
c[i] = 0 ;
for ( int i = 0 ; i < d; i ++ )
{
for ( int j = 0 ; j < length; j ++ )
{
int temp = getBit(a[j], i, radix);
remainder[j] = temp;
c[temp] ++ ;
}
for ( int k = 1 ; k < radix; k ++ )
c[k] = c[k] + c[k - 1 ];
for ( int k = length - 1 ; k >= 0 ; k -- )
{
b[ -- c[remainder[k]]] = a[k];
// c[remainder[k]]--;
}
for ( int k = 0 ; k < radix; k ++ )
c[k] = 0 ;
for ( int i = 0 ; i < length; i ++ )
a[i] = b[i];
}
delete remainder;
delete c;
delete b;
}
// 得到相应位上的数值
int getBit( int m, int i, int radix)
{
return (m % (pow2(radix, i + 1 ))) / pow2(radix, i);
}
// 只处理指数b>=0
int pow2( int a, int b)
{
if (b > 0 )
{
int result = a;
for ( int i = 0 ; i < b - 1 ; i ++ )
result = result * a;
return result;
}
else if (b == 0 )
return 1 ;
else
{
cout << " 不处理指数小于零的情况 " << endl;
return - 1 ;
}
}
#include < math.h >
using namespace std;
void radix_sort( int a[], const int d, const int length, int radix);
int getBit( int m, int i, int radix);
int pow2( int a, int b);
int main()
{
// 数组长度
const int LEN = 15 ;
int a[LEN] = { 35 , 48 , 0 , 8 , 15 , 80 , 99 , 3 , 24 , 168 , 195 , 224 , 63 , 120 , 143 };
// 多少位
const int d = 2 ;
// 基数
const int radix = 15 ;
// 在这调用的是通用的基数排序算法,可以任意改变基数radix,
// 但记得改变d,因为radix改变的话,数字的位数会改变,
// 最简单的是十进制改成二进制,位数激增
radix_sort(a, d, LEN, radix);
for ( int i = 0 ; i < LEN; i ++ )
cout << a[i] << endl;
}
void radix_sort( int a[], const int d, const int length, int radix)
{
// 存储a中每个元素的余数
int * remainder = new int [length];
// 统计余数(等同于计数排序中的c)
int * c = new int [radix];
// 保存排序之后的a
int * b = new int [length];
for ( int i = 0 ; i < radix; i ++ )
c[i] = 0 ;
for ( int i = 0 ; i < d; i ++ )
{
for ( int j = 0 ; j < length; j ++ )
{
int temp = getBit(a[j], i, radix);
remainder[j] = temp;
c[temp] ++ ;
}
for ( int k = 1 ; k < radix; k ++ )
c[k] = c[k] + c[k - 1 ];
for ( int k = length - 1 ; k >= 0 ; k -- )
{
b[ -- c[remainder[k]]] = a[k];
// c[remainder[k]]--;
}
for ( int k = 0 ; k < radix; k ++ )
c[k] = 0 ;
for ( int i = 0 ; i < length; i ++ )
a[i] = b[i];
}
delete remainder;
delete c;
delete b;
}
// 得到相应位上的数值
int getBit( int m, int i, int radix)
{
return (m % (pow2(radix, i + 1 ))) / pow2(radix, i);
}
// 只处理指数b>=0
int pow2( int a, int b)
{
if (b > 0 )
{
int result = a;
for ( int i = 0 ; i < b - 1 ; i ++ )
result = result * a;
return result;
}
else if (b == 0 )
return 1 ;
else
{
cout << " 不处理指数小于零的情况 " << endl;
return - 1 ;
}
}