100000个随机数排序

问题

时间要求:1000ms

随机数范围:0--100000(8位小数)

考虑使用基数排序

  1. 无空间要求
  2. 随机数范围较小,不会占用过多的空间(空间过大也会使基数排序的时间变长)
思路:

  1. 生成随机数
  2. 使用基数排序:将整数部分相同的数看作相等的数,并记录下不同整数对应的随机数的个数和对应的索引起始位置
    • 基数排序后:如下所示,按照整数部分是有序的
    • 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;
	}
}



  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值