2013-07-10 18:39:25
【编程珠玑】读书笔记第一章
本书以一个排序的问题开篇,讨论了排序的最佳方法,并引入了位图排序的算法。实际上,此处的位图排序本质就是计数排序(关于计数排序,此处不再赘述),只不过由于此处问题的特殊性——数据没有重复,可使用更加节省空间的方法,对每一个数据,使用1bit的空间进行计数。
书中还给出了用标准库函数qsort、以及模板类set排序的提议,以与位图排序的性能进行比较,下面给出了几中排序方法,包括:
- 使用模板类bitset作为计数数组实现位图排序,具体实现见代码中BitmapSort_1函数;
- 用int型数据模拟bit型的操作实现位图排序,具体实现见下面代码中BitmapSort_2函数,该函数可在C语言下实现;
- 用标准库函数qsort实现排序,具体实现见下面代码中main函数中qsort;
- 用C++的模板类set或multiset实现排序;
上面几种方法,方法2是书中的方法,且可以用C语言实现,qsort也可用C语言实现,而其他两种方法必须用C++实现。使用前2中方法会受到用位图排序的使用场合的限制,而后面两种则没有限制。
下面给出上述4中方法的源代码实现,以及性能分析。
注意,性能分析部分的代码相对于前面的是有改动的,以性能分析部分的代码为最终的。
位图排序以及使用标准库函数qsort的排序
用位图排序的使用场合以及限制条件:
- 待排序数组为非负数;
-
输入数据限制在相对较小的范围内;
- 数组元素不重复,若有重复,排序后数组会丢弃重复的元素;
上面已经提到过位图排序本质就是计数排序,而计数排序要准备一个用于计数的数组,对于位图,就是bit类型的数组。
在C++中,可以使用模板类bitset作为计数数组,具体实现见代码中BitmapSort_1函数。但在C语言中没有该类型的数据的,书中给出了一种用int型数据模拟bit型的操作,具体实现见下面代码中BitmapSort_2函数。
位图排序的实现,注意几点:
- 在使用必须确保计数数组初初始化为全0:对于用C++中模板类bitset实现的位图排序的BitmapSort_1函数,即:Bitmap.reset();对于用int型数组模拟位图的BitmapSort_2函数,即BitmapArray[1 + N/BitsPerInt] = {0};
- 注意语句 int BitmapArray[1 + N/BitsPerInt] = {0}; 将会初始化数组所有元素,而不只是第一个;
对qsort,注意:
- comp函数的参数类型必须为const类型,这是由qsort函数中参数cmp的类型决定的。
int comp(void *_p,void *_q) //提示cannot convert parameter 4 from 'int (__cdecl *)(void *,void *)' to 'int (__cdecl *)(const void *,const void *)'
int comp(const void *_p,const void *_q)
用int型模拟位图的关键在与如何实现每个bit的置位、清零以及判断是否为1,书中给出了一种用位运算的方法,如下:
1 //用int型模拟位图,实现的位图排序 2 const int BitsPerInt = 32; 3 const int Div32Shift = 5; 4 const int Mod32Mask = 0x1F; 5 6 //BitmapSort_2:用位运算实现置位、清零、判断是否为1 7 void SetBit(int BitmapArray[],const int BitToSet) 8 { 9 //BitmapArray[ (BitToSet >> Div32Shift) ] | = ( 1 << (BitToSet & Mod32Mask) ); //error C2059: syntax error : '=' 10 BitmapArray[ (BitToSet >> Div32Shift) ] = BitmapArray[ (BitToSet >> Div32Shift) ] 11 | ( 1 << (BitToSet & Mod32Mask) ); 12 } 13 14 void ClearBit(int BitmapArray[],const int BitToClear) 15 { 16 BitmapArray[ (BitToClear >> Div32Shift) ] = BitmapArray[ (BitToClear >> Div32Shift) ] 17 & ~( 1 << (BitToClear & Mod32Mask) ); 18 } 19 20 //bool IsBitSet(int BitmapArray[],const int BitToSet) 21 bool IsBitSet(const int BitmapArray[],const int BitToCheck) //定义为const类型,在不小心改变时,会给出报错信息 22 { 23 return ( BitmapArray[ (BitToCheck >> Div32Shift) ] & ( 1 << (BitToCheck & Mod32Mask) ) ); 24 }
位图排序完整代码:
1 #include <iostream> 2 #include <bitset> 3 #include <set> 4 using namespace std; 5 #define N 10 6 7 //BitmapSort_1:用C++中模板类bitset实现的位图排序 8 void BitmapSort_1(int ArrayUnsorted[],int n) 9 { 10 bitset <N> Bitmap; 11 int * ArraySorted = new int[n]; 12 int cnt = 0; 13 Bitmap.reset(); //清零,保证使用之前全部为0 14 15 int i ; 16 for (i = 0;i < n;++i) //标记各个位置 17 { 18 Bitmap.set(ArrayUnsorted[i]); 19 } 20 21 for (i = 0;i < n;++i) 22 { 23 if ( Bitmap[i] ) //如果位置i为1,则说明i在数组ArraySorted中出现,且为排序后的第cnt个 24 { 25 ArrayUnsorted[cnt++] = i; 26 } 27 } 28 } 29 30 //用int型模拟位图,实现的位图排序 31 const int BitsPerInt = 32; 32 const int Div32Shift = 5; 33 const int Mod32Mask = 0x1F; 34 35 //BitmapSort_2:用位运算实现置位、清零、判断是否为1 36 void SetBit(int BitmapArray[],const int BitToSet) 37 { 38 //BitmapArray[ (BitToSet >> Div32Shift) ] | = ( 1 << (BitToSet & Mod32Mask) ); //error C2059: syntax error : '=' 39 BitmapArray[ (BitToSet >> Div32Shift) ] = BitmapArray[ (BitToSet >> Div32Shift) ] 40 | ( 1 << (BitToSet & Mod32Mask) ); 41 } 42 43 void ClearBit(int BitmapArray[],const int BitToClear) 44 { 45 BitmapArray[ (BitToClear >> Div32Shift) ] = BitmapArray[ (BitToClear >> Div32Shift) ] 46 & ~( 1 << (BitToClear & Mod32Mask) ); 47 } 48 49 //bool IsBitSet(int BitmapArray[],const int BitToSet) 50 bool IsBitSet(const int BitmapArray[],const int BitToCheck) //定义为const类型,在不小心改变时,会给出报错信息 51 { 52 return ( BitmapArray[ (BitToCheck >> Div32Shift) ] & ( 1 << (BitToCheck & Mod32Mask) ) ); 53 } 54 55 void BitmapSort_2(int ArrayUnsorted[],const int n) 56 { 57 int BitmapArray[1 + N/BitsPerInt] = {0}; //将会初始化数组所有元素,而不只是第一个 58 int i ; 59 int cnt = 0; 60 61 for (i = 0;i < n;++i) 62 { 63 SetBit(BitmapArray,ArrayUnsorted[i]); 64 } 65 66 for (i = 0;i < n;++i) 67 { 68 if ( IsBitSet(BitmapArray,i) ) 69 { 70 ArrayUnsorted[cnt++] = i; 71 cout<<ArrayUnsorted[cnt - 1]<<endl; 72 } 73 } 74 } 75 76 77 //注意参数必须为const类型 78 //int comp(void *_p,void *_q) //提示cannot convert parameter 4 from 'int (__cdecl *)(void *,void *)' to 'int (__cdecl *)(const void *,const void *)' 79 int comp(const void *_p,const void *_q) 80 { 81 int *p = (int *)_p; 82 int *q = (int *)_q; 83 return (*p - *q); 84 } 85 86 //不需要写初始化函数,因为在定义的时候可以初始化 87 void Init(int BitmapArray[],const int n) 88 { 89 for (int i = 0;i < n;++i) 90 { 91 BitmapArray[i] = 0; 92 } 93 } 94 95 //显示数组元素 96 void DisplayArray(int ArrayUnsorted[],int n) 97 { 98 for (int i = 0;i < n;++i) 99 { 100 cout<<ArrayUnsorted[i]<<" "; 101 } 102 cout<<endl; 103 } 104 105 //测试程序 106 int main() 107 { 108 //int ArrayUnsorted[N] = {7,9,2,3, 4,5,1,8, 0,6}; 109 int ArrayUnsorted[N] = {7,9,2,2, 4,8,1,8, 0,6}; 110 111 cout<<"the unsorted array is : "<<endl; 112 DisplayArray(ArrayUnsorted,N); 113 114 //测试BitmapSort_1 115 /*cout<<"Test BitmapSort_1..."<<endl; 116 BitmapSort(ArrayUnsorted,N); 117 cout<<"the sorted array is : "<<endl; 118 DisplayArray(ArrayUnsorted,N); */ 119 120 //测试BitmapSort_2 121 cout<<"Test BitmapSort_2..."<<endl; 122 BitmapSort_2(ArrayUnsorted,N); 123 cout<<"the sorted array is : "<<endl; 124 DisplayArray(ArrayUnsorted,N); 125 126 //测试系统函数qsort 127 /*cout<<"Test qsort..."<<endl; 128 qsort(ArrayUnsorted,N,sizeof(int),comp); 129 cout<<"the sorted array is : "<<endl; 130 DisplayArray(ArrayUnsorted,N); */ 131 132 return 0; 133 }
使用C++ STL中的标准关联容器set排序
set 是一个容器,它用于储存数据并且能从一个数据集合中取出数据。它的每个元素的值必须惟一,而且系统会根据该值来自动将数据排序。每个元素的值不能直接被改变。
multiset与set的不同之处就是key可以重复,以及erase(key)的时候会删除multiset里面所有的key并且返回删除的个数。
注意几点:
iterator不支持运算<,因此不能用下面的方式控制循环
for (iter = SetForSort.begin();iter < SetForSort.end();++iter)
而应采用如下方式:
for (iter = SetForSort.begin();iter != SetForSort.end();++iter)
会给出出错信息如下:
binary '<' : 'std::_Tree_const_iterator<_Mytree>' does not define this operator or a conversion to a type acceptable to the predefined operator
用下面的方式将排序结果输出到ArrayUnsorted数组,在元素有重复时,容器访问会发生越界,因为容器中元素个数小于n
1 for (i = 0;i < n;++i) 2 3 { 4 ArrayUnsorted[i] = *iter++; 5 }
因为排序后的数组是在容器中存放的,所以直接采用容器的begin与end控制比较好,如下:
1 for (iter = SetForSort.begin();iter != SetForSort.end();++iter) 2 { 3 ArrayUnsorted[cnt++] = *iter; 4 }
完整代码:
1 #include <iostream> 2 #include <set> 3 using namespace std; 4 #define N 10 5 6 //没有加入合法性检查以及出错处理,只是实现了函数的功能 7 //使用C++ STL中的标准关联容器set排序 8 void SetContainerSort(int ArrayUnsorted[],int n) 9 { 10 //set <int> SetForSort; //使用set,元素不可重复 11 //set <int> :: const_iterator iter = SetForSort.begin(); 12 multiset <int> SetForSort; //使用multiset,元素可重复 13 multiset <int> :: const_iterator iter = SetForSort.begin(); 14 int i; 15 int cnt = 0; 16 17 for (i = 0;i < n;++i) 18 { 19 SetForSort.insert(ArrayUnsorted[i]); 20 } 21 22 for (iter = SetForSort.begin();iter != SetForSort.end();++iter) 23 { 24 ArrayUnsorted[cnt++] = *iter; 25 } 26 } 27 28 //显示数组元素 29 void DisplayArray(int ArrayUnsorted[],int n) 30 { 31 for (int i = 0;i < n;++i) 32 { 33 cout<<ArrayUnsorted[i]<<" "; 34 } 35 cout<<endl; 36 } 37 38 //测试程序 39 int main() 40 { 41 int ArrayUnsorted[N] = {7,9,2,3, 4,5,1,8, 0,6}; //元素互为不同,且都是正数 42 //int ArrayUnsorted[N] = {7,9,2,3, 4,5,2,8, 7,6}; //元素有重复,且都是正数 43 //int ArrayUnsorted[N] = {7,9,-1,3, 4,5,-2,8, -7,-6}; //元素有负数,且都是正数 44 45 cout<<"the unsorted array is : "<<endl; 46 DisplayArray(ArrayUnsorted,N); 47 48 //测试SetContainerSort 49 cout<<"Test SetContainerSort..."<<endl; 50 SetContainerSort(ArrayUnsorted,N); 51 cout<<"the sorted array is : "<<endl; 52 DisplayArray(ArrayUnsorted,N); 53 54 return 0; 55 }
使用set或multiset容器,都可对不同类型的数进行排序,当然也可对含有负数的int数组排序。
因为set容器中的元素必须唯一,元素重复时会被忽略,所以使用set容器时,若输入元素有重复,利用set排序的结果会有丢失,在main中测试用第二行的数组时,运行结果如下:
the unsorted array is : 7 9 2 3 4 5 2 8 7 6 Test SetContainerSort... the sorted array is : 2 3 4 5 6 7 8 9 7 6 请按任意键继续. . .
可以看到,set容器忽略了重复的元素,输出的7、6是原数组的元素。
若将使用的容器改为multiset,可正确排序,运行结果如下:
the unsorted array is : 7 9 2 3 4 5 2 8 7 6 Test SetContainerSort... the sorted array is : 2 2 3 4 5 6 7 7 8 9 请按任意键继续. . .
性能分析
结论:
BitmapSort_1是最快的,在数组长度为10,0000时,其速度比BitmapSort_2大概快一倍,应该是利用了STL中的bitset的优势,对bit的操作更快;
BitmapSort_2速度次之,qsort更次,而用set容器是最慢的,在数组成都为1000,0000时,性能的差别更为明显。
注意几点:
用clock()函数计时,分析时间性能,如下:
sortStartTime = clock();
BitmapSort_2(ArrayUnsorted,numberOfRandomInt);
TimeCost = 1e6 * ( clock() - sortStartTime ) / CLOCKS_PER_SEC;
通过程序运行前后的时间差,得到程序的运行时间。
栈内存是有限的,本程序中若数组长度为1000,0000如果在使用栈内存,程序运行时崩溃,单步跟踪,则会提示栈溢出,如下:
因此,在使用空间较大时,应在堆上分配内存,对于BitmapSort_2,将
int BitmapArray[1 + MaxRandomInt/BitsPerInt] = {0};
改为int *BitmapArray = new int[1 + MaxRandomInt/BitsPerInt];
并注意加上数组的初始化。
另外,对于位图排序,还应注意,最后for循环的结束条件是i < MaxRandomInt,而不是i < n,如下:
1 for (i = 0;i < MaxRandomInt;++i) //不是for (i = 0;i < n;++i) 2 { 3 if ( IsBitSet(BitmapArray,i) ) 4 { 5 ArrayUnsorted[cnt++] = i; 6 } 7 }
时间开销分析完整代码:
1 #include <iostream> 2 #include <bitset> 3 #include <set> 4 #include <ctime> 5 using namespace std; 6 7 const int MaxRandomInt = 10000000; 8 const int NumberToSort = 1000000; 9 10 //产生在区间[lowerBound,upperBound]内的一个随机数 11 int RandomInt(const int lowerBound,const int upperBound) 12 { 13 return ( lowerBound + ( RAND_MAX * rand() + rand() ) % (upperBound - lowerBound + 1) ); 14 } 15 16 //产生在[0,maxOfRandomInt]范围内的numberOfRandomInt个随机数 17 //结果存入数组randomInt中 18 void RandomIntGen(const int numberOfRandomInt,const int maxOfRandomInt,int randomInt[]) 19 { 20 int i; 21 int tmp; 22 int randomTmp; 23 int *sequenceInt = new int[maxOfRandomInt]; 24 25 srand((unsigned) time(NULL)); 26 27 for (i = 0; i < maxOfRandomInt; i++) 28 { 29 sequenceInt[i] = i; 30 } 31 32 for (i = 0; i < numberOfRandomInt; i++) 33 { 34 randomTmp = RandomInt(i, maxOfRandomInt - 1); 35 tmp = sequenceInt[randomTmp]; 36 sequenceInt[randomTmp] = sequenceInt[i]; 37 sequenceInt[i] = tmp; 38 randomInt[i] = sequenceInt[i]; //随机数保存在数组中 39 } 40 41 delete [] sequenceInt; //释放内存 42 } 43 44 //BitmapSort_1:用C++中模板类bitset实现的位图排序 45 void BitmapSort_1(int ArrayUnsorted[],int n) 46 { 47 bitset <MaxRandomInt> Bitmap; 48 int * ArraySorted = new int[n]; 49 int cnt = 0; 50 Bitmap.reset(); //清零,保证使用之前全部为0 51 52 int i ; 53 for (i = 0;i < n;++i) //标记各个位置 54 { 55 Bitmap.set(ArrayUnsorted[i]); 56 } 57 58 for (i = 0;i < n;++i) 59 { 60 if ( Bitmap[i] ) //如果位置i为1,则说明i在数组ArraySorted中出现,且为排序后的第cnt个 61 { 62 ArrayUnsorted[cnt++] = i; 63 } 64 } 65 } 66 67 //不需要写初始化函数,因为在定义的时候可以初始化 68 void Init(int BitmapArray[],const int n) 69 { 70 for (int i = 0;i < n;++i) 71 { 72 BitmapArray[i] = 0; 73 } 74 } 75 76 //用int型模拟位图,实现的位图排序 77 const int BitsPerInt = 32; 78 const int Div32Shift = 5; 79 const int Mod32Mask = 0x1F; 80 81 //BitmapSort_2:用位运算实现置位、清零、判断是否为1 82 void SetBit(int BitmapArray[],const int BitToSet) 83 { 84 //BitmapArray[ (BitToSet >> Div32Shift) ] | = ( 1 << (BitToSet & Mod32Mask) ); //error C2059: syntax error : '=' 85 BitmapArray[ (BitToSet >> Div32Shift) ] = BitmapArray[ (BitToSet >> Div32Shift) ] 86 | ( 1 << (BitToSet & Mod32Mask) ); 87 } 88 89 void ClearBit(int BitmapArray[],const int BitToClear) 90 { 91 BitmapArray[ (BitToClear >> Div32Shift) ] = BitmapArray[ (BitToClear >> Div32Shift) ] 92 & ~( 1 << (BitToClear & Mod32Mask) ); 93 } 94 95 //bool IsBitSet(int BitmapArray[],const int BitToSet) 96 bool IsBitSet(const int BitmapArray[],const int BitToCheck) //定义为const类型,在不小心改变时,会给出报错信息 97 { 98 return ( BitmapArray[ (BitToCheck >> Div32Shift) ] & ( 1 << (BitToCheck & Mod32Mask) ) ); 99 } 100 101 void BitmapSort_2(int ArrayUnsorted[],const int n) 102 { 103 int i ; 104 int cnt = 0; 105 //int BitmapArray[1 + MaxRandomInt/BitsPerInt] = {0}; //将会初始化数组所有元素,而不只是第一个 106 int *BitmapArray = new int[1 + MaxRandomInt/BitsPerInt]; //当MaxRandomInt较大时,必须从对上分配内存,否则内存不够用,导致出错 107 108 if (NULL == BitmapArray) 109 { 110 cout<<"memory allocation error !"<<endl; 111 exit(0); 112 } 113 114 Init(BitmapArray,1 + MaxRandomInt/BitsPerInt); //初始化为0 115 116 for (i = 0;i < n;++i) 117 { 118 SetBit(BitmapArray,ArrayUnsorted[i]); 119 } 120 121 /*for (i = 0;i < n;++i) 122 { 123 if ( IsBitSet(BitmapArray,i) ) 124 { 125 ArrayUnsorted[cnt++] = i; 126 } 127 }*/ 128 129 for (i = 0;i < MaxRandomInt;++i) 130 { 131 if ( IsBitSet(BitmapArray,i) ) 132 { 133 ArrayUnsorted[cnt++] = i; 134 } 135 } 136 137 delete [] BitmapArray; 138 } 139 140 //没有加入合法性检查以及出错处理,只是实现了函数的功能 141 //使用C++ STL中的标准关联容器set排序 142 void SetContainerSort(int ArrayUnsorted[],int n) 143 { 144 //set <int> SetForSort; //使用set,元素不可重复 145 //set <int> :: const_iterator iter = SetForSort.begin(); 146 multiset <int> SetForSort; //使用multiset,元素可重复 147 multiset <int> :: const_iterator iter = SetForSort.begin(); 148 int i; 149 int cnt = 0; 150 151 for (i = 0;i < n;++i) 152 { 153 SetForSort.insert(ArrayUnsorted[i]); 154 } 155 156 for (iter = SetForSort.begin();iter != SetForSort.end();++iter) 157 { 158 ArrayUnsorted[cnt++] = *iter; 159 } 160 } 161 162 163 //注意参数必须为const类型 164 //int comp(void *_p,void *_q) //提示cannot convert parameter 4 from 'int (__cdecl *)(void *,void *)' to 'int (__cdecl *)(const void *,const void *)' 165 int comp(const void *_p,const void *_q) 166 { 167 int *p = (int *)_p; 168 int *q = (int *)_q; 169 return (*p - *q); 170 } 171 172 //显示数组元素 173 void DisplayArray(int ArrayUnsorted[],int n) 174 { 175 for (int i = 0;i < n;++i) 176 { 177 cout<<ArrayUnsorted[i]<<" "; 178 } 179 cout<<endl; 180 } 181 182 void WriteArrayToUnsortedTxt(int array[],int n) 183 { 184 FILE *fout; 185 int i; 186 187 fout = fopen("array_unsorted.txt","wt"); 188 189 if(fout == NULL) 190 { 191 printf("forward_i.txt open error! "); 192 exit(0); 193 } 194 195 printf("file open success! "); 196 197 for (i = 0;i < n;i++) 198 { 199 fprintf(fout,"%d ",array[i]); 200 } 201 202 fclose(fout); 203 } 204 205 void WriteArrayToSortedTxt(int array[],int n) 206 { 207 FILE *fout; 208 int i; 209 210 fout = fopen("array_sorted.txt","wt"); 211 212 if(fout == NULL) 213 { 214 printf("forward_i.txt open error! "); 215 exit(0); 216 } 217 218 printf("file open success! "); 219 220 for (i = 0;i < n;i++) 221 { 222 fprintf(fout,"%d ",array[i]); 223 } 224 225 fclose(fout); 226 } 227 228 //测试程序 229 int main() 230 { 231 const int numberOfRandomInt = NumberToSort; 232 const int maxOfRandomInt = MaxRandomInt; 233 int *ArrayUnsorted = new int[NumberToSort]; 234 int sortStartTime = 0; 235 int TimeCost = 0; 236 237 cout<<"the number of integer to sort is : "<<numberOfRandomInt<<endl; 238 239 RandomIntGen(numberOfRandomInt,maxOfRandomInt,ArrayUnsorted); 240 WriteArrayToUnsortedTxt(ArrayUnsorted,numberOfRandomInt); 241 /*cout<<"the randomInt array is :"<<endl; 242 DisplayArray(ArrayUnsorted,numberOfRandomInt);*/ 243 244 //测试BitmapSort_1 245 /*cout<<"Test BitmapSort_1..."<<endl; 246 247 sortStartTime = clock(); 248 BitmapSort_1(ArrayUnsorted,numberOfRandomInt); 249 TimeCost = 1e6 * ( clock() - sortStartTime ) / CLOCKS_PER_SEC; 250 cout<<"the time cost of BitmapSort_1 is : "<<TimeCost<<"ms"<<endl; 251 252 WriteArrayToSortedTxt(ArrayUnsorted,numberOfRandomInt);*/ 253 /*cout<<"the sorted array is : "<<endl; 254 DisplayArray(ArrayUnsorted,N); */ 255 256 //测试BitmapSort_2 257 cout<<"Test BitmapSort_2..."<<endl; 258 259 sortStartTime = clock(); 260 BitmapSort_2(ArrayUnsorted,numberOfRandomInt); 261 TimeCost = 1e6 * ( clock() - sortStartTime ) / CLOCKS_PER_SEC; 262 cout<<"the time cost of BitmapSort_2 is : "<<TimeCost<<"ms"<<endl; 263 264 WriteArrayToSortedTxt(ArrayUnsorted,numberOfRandomInt); 265 /*cout<<"the sorted array is : "<<endl; 266 DisplayArray(ArrayUnsorted,N); */ 267 268 //测试SetContainerSort 269 cout<<"Test SetContainerSort..."<<endl; 270 271 sortStartTime = clock(); 272 SetContainerSort(ArrayUnsorted,numberOfRandomInt); 273 TimeCost = 1e6 * ( clock() - sortStartTime ) / CLOCKS_PER_SEC; 274 cout<<"the time cost of SetContainerSort is : "<<TimeCost<<"ms"<<endl; 275 276 WriteArrayToSortedTxt(ArrayUnsorted,numberOfRandomInt); 277 /*cout<<"the sorted array is : "<<endl; 278 DisplayArray(ArrayUnsorted,N); */ 279 280 //测试系统函数qsort 281 cout<<"Test qsort..."<<endl; 282 283 sortStartTime = clock(); 284 qsort(ArrayUnsorted,numberOfRandomInt,sizeof(int),comp); 285 TimeCost = 1e6 * ( clock() - sortStartTime ) / CLOCKS_PER_SEC; 286 cout<<"the time cost of qsort is : "<<TimeCost<<"ms"<<endl; 287 288 WriteArrayToSortedTxt(ArrayUnsorted,numberOfRandomInt); 289 /*cout<<"the sorted array is : "<<endl; 290 DisplayArray(ArrayUnsorted,N); */ 291 292 delete [] ArrayUnsorted; //delete与new要配对出现 293 294 return 0; 295 }
对于用bitset容器的位图排序方法,由于bitset <MaxRandomInt> Bitmap;定义的Bitmap是在栈上的,当待排序数组长度为100,0000时,程序出错,提示栈溢出,因此采用数据个数为10,0000,分析,运行结果如下:
the number of integer to sort is : 100000 file open success! Test BitmapSort_1... the time cost of BitmapSort_1 is : 65000ms file open success! Test BitmapSort_2... the time cost of BitmapSort_2 is : 120000ms file open success! Test SetContainerSort... the time cost of SetContainerSort is : 4027000ms file open success! Test qsort... the time cost of qsort is : 131000ms file open success! 请按任意键继续. . .
对于其他三种方法,因为空间可以在堆上,待排序数组长度为1000,0000时,内存分配也不会出错,运行结果如下:
the number of integer to sort is : 1000000 file open success! Test BitmapSort_2... the time cost of BitmapSort_2 is : 869000ms file open success! Test SetContainerSort... the time cost of SetContainerSort is : 39168000ms file open success! Test qsort... the time cost of qsort is : 2200000ms file open success! 请按任意键继续. . .
可以看到,BitmapSort_1是最快的,在数组长度为10,0000时,其速度比BitmapSort_2大概快一倍,应该是利用了STL中的bitset的优势,对bit的操作更快;
BitmapSort_2速度次之,qsort更次,而用set容器是最慢的,在数组成都为1000,0000时,性能的差别更为明显。