时间要求:1000ms
随机数范围:0--100000(8位小数)
考虑使用基数排序
- 无空间要求
- 随机数范围较小,不会占用过多的空间(空间过大也会使基数排序的时间变长)
- 生成随机数
- 使用基数排序:将整数部分相同的数看作相等的数,并记录下不同整数对应的随机数的个数和对应的索引起始位置
- 基数排序后:如下所示,按照整数部分是有序的
- 1.6556121416647251454
1.4787539846629074169
2.8446782393586205195
2.6157125842828077289
4.3215230127426771389
4.6877656153807230055
5.8033503619032469345
8.0382917113772442974
9.2728529168622859657
10.722782467827425279
10.386807848878474303
12.361258274111246891
12.033525859951479831
12.678420177044205985
14.090584597591105265
17.943605788955348856
17.623184257009718579 - 根据记录下的每个整数部分对应的起始位置和数量进行局部的排序,建议使用非递归类的算法:冒泡、选择都可以,因为递归调用会找用一定的时间,而且最好不使用函数调用
- 排序之后:
- 1.4787539846629074169
1.6556121416647251454
2.6157125842828077289
2.8446782393586205195
4.3215230127426771389
4.6877656153807230055
5.8033503619032469345
8.0382917113772442974
9.2728529168622859657
10.386807848878474303
10.722782467827425279
12.033525859951479831
12.361258274111246891
12.678420177044205985
14.090584597591105265
17.623184257009718579
17.943605788955348856
19.786646598848701473
20.338036129406500407
21.463865424254564118
21.617114553978886704
测试:
time ./sort > sorted.txt
real 0m0.596s
user 0m0.352s
sys 0m0.240s
以上时间包括了生成随机数、排序和写入文件所用的时间 :)
下面是代码:
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<iomanip>
using namespace std;
using std::setprecision;
#define SIZE 100000
#define MAX 100000
/*
1000ms
100000
100000.00000000
space <---> time
*/
double fRand(double fMin, double fMax);
int main(void){
//gen
double arrData[SIZE];
for( int i=0; i<SIZE; i++ ){
arrData[i] = fRand( 0, 99999.99999999 );
}
//---gen
//sort
//base number sort and non-unique
int arrCount[MAX];
int arrCountTemp[MAX];
int arrStartTemp[MAX];
for( int i=0; i<MAX; i++ ){
arrCount[i] = 0;
arrCountTemp[i] = 0;
arrStartTemp[i] = 0;
}
for( int i=0; i<SIZE; i++ ){
arrCount[ (int)arrData[i] ]++;
arrCountTemp[ (int)arrData[i] ]++;
}
for( int i=1; i<MAX; i++ ){
arrCount[i] = arrCount[i] + arrCount[i-1];
arrStartTemp[i] = arrCount[i-1];
}
double arrNew[SIZE];
for( int i=0; i<SIZE; i++ ){
arrNew[arrCount[(int)arrData[i]] - 1 ] = arrData[i];//0 based,第一个
arrCount[(int)arrData[i]]--;
}
for( int i=0; i<MAX; i++ ){
//sort( arrNew, curStart, curStart+countCur );
for( int out=arrStartTemp[i]+arrCountTemp[i]-1; out>=arrStartTemp[i]+1; out-- ){
for( int in=arrStartTemp[i]+1; in<=out; in++ ){
if( arrNew[in]<arrNew[in-1] ){
double temp = arrNew[in];
arrNew[in] = arrNew[in-1];
arrNew[in-1] = temp;
}
}
}
}
//---sort
//show
for(int i=1; i<=SIZE; i++){
cout<<setprecision(20)<<arrNew[i]<<endl;
}
//---show
}
double fRand(double fMin, double fMax)
{
while(true){
double f = (double)rand() / RAND_MAX;
double r = fMin + f * (fMax - fMin);
if(r>=0)
return r;
}
}