第三题:
位图法的时间复杂度是O(N)。
STL 快排时间复杂度是O(K*log(K))。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <windows.h>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;
#define N 10000000
#define K 1000000
class PearlsCh1{
public:
void shuffle(vector<int> &v){
srand((unsigned)time(NULL));
int len = v.size();
int factor = len/RAND_MAX+1;
for(int i=0;i<len-1;++i){
int j = (rand()*factor)%(len-i);
int tmp = v[i];
v[i] = v[i+j];
v[i+j] = tmp;
}
}
void gen_file(const char *path, int n){
FILE *f = fopen(path,"w");
vector<int> v(N);
for(int i=0;i<N;++i)
v[i] = i;
shuffle(v);
//random_shuffle(v.begin(),v.end());
for(int i=0;i<n;++i)
fprintf(f,"%d\n",v[i]);
fclose(f);
}
void bit_sort(const char *path, const char *output){
bitset<N> set(0);
FILE *f = fopen(path,"r");
int num;
cout<<"read file"<<endl;
int count=0;
while(fscanf(f,"%d",&num)>0){
set[num] = 1;
}
fclose(f);
cout<<"read finished, begin to sort"<<endl;
f = fopen(output,"w");
for(int i=0;i<N;++i){
if(set[i]){
fprintf(f,"%d\n",i);
}
}
fclose(f);
}
void quick_sort(const char *path, const char *output){
vector<int> v(K);
FILE *f = fopen(path,"r");
int num;
int count=0;
cout<<"read file"<<endl;
while(fscanf(f,"%d",&num)>0){
v[count++] = num;
}
cout<<"read finished, begin to sort"<<endl;
sort(v.begin(),v.end());
f = fopen(output,"w");
for(int i=0;i<K;++i){
fprintf(f,"%d\n",v[i]);
}
fclose(f);
}
};
首先产生一个数字文件,该文件包含100万个小于1000万的随机数字,并没有重复。
shuffle函数,打乱vector中元素顺序。
这里要注意rand()产生的随机数最大值为RAND_MAX,在我的系统上是3万多,因为要打乱1千万个数字,所以得将产生的随机数放大到1千万数量级。
产生numbers.txt文件,其包含1千万个不重复的小于1千万的数字。
这里如果用的是windows的编译器由于栈空间只有1M,所以用bitset的话1千万会溢出。
要么修改编译器连接选项栈空间设置大一些,要么在堆上建bitset。这里n=1000000。
然后main函数中测试其排序时间:
int main(){ clock_t start, end; PearlsCh1 p; start = clock(); p.bit_sort("D:\\Pearls\\numbers.txt","D:\\Pearls\\bit_sorted.txt"); end = clock(); cout<<end-start<<endl; start = clock(); p.quick_sort("D:\\Pearls\\numbers.txt","D:\\Pearls\\quick_sorted.txt"); end = clock(); cout<<end-start<<endl; getchar(); return 0; }
主要时间应花在IO上了。
位图:3696 ms
快排:3994 ms
第九题:
data数组为未初始化的数据。
from[i]表示第i个元素是第from[i]个被初始化的。
to[i]表示第i个被初始化的元素是data中的第to[i]个元素。
这样,当访问到data[i]时,如果from[i]<top则说明这个元素有可能已经被访问过了(也有可能是内存中的随机数据正好<top)。
此时to[from[i]]表示第from[i]个被初始化的元素是data中的第几个元素。如果等于i,说明data[i]确实被访问过了,from[i]中的不是随机数据。