【编程珠玑】读书笔记 第一章 开篇

2013-07-10 18:39:25

【编程珠玑】读书笔记第一章

  本书以一个排序的问题开篇,讨论了排序的最佳方法,并引入了位图排序的算法。实际上,此处的位图排序本质就是计数排序(关于计数排序,此处不再赘述),只不过由于此处问题的特殊性——数据没有重复,可使用更加节省空间的方法,对每一个数据,使用1bit的空间进行计数。

  书中还给出了用标准库函数qsort、以及模板类set排序的提议,以与位图排序的性能进行比较,下面给出了几中排序方法,包括:

  1. 使用模板类bitset作为计数数组实现位图排序,具体实现见代码中BitmapSort_1函数;
  2. 用int型数据模拟bit型的操作实现位图排序,具体实现见下面代码中BitmapSort_2函数,该函数可在C语言下实现;
  3. 用标准库函数qsort实现排序,具体实现见下面代码中main函数中qsort;
  4. 用C++的模板类set或multiset实现排序;

  上面几种方法,方法2是书中的方法,且可以用C语言实现,qsort也可用C语言实现,而其他两种方法必须用C++实现。使用前2中方法会受到用位图排序的使用场合的限制,而后面两种则没有限制。

  下面给出上述4中方法的源代码实现,以及性能分析。

注意,性能分析部分的代码相对于前面的是有改动的,以性能分析部分的代码为最终的。


 

位图排序以及使用标准库函数qsort的排序

用位图排序的使用场合以及限制条件:

  1. 待排序数组为非负数;
  2. 输入数据限制在相对较小的范围内;

  3. 数组元素不重复,若有重复,排序后数组会丢弃重复的元素;

上面已经提到过位图排序本质就是计数排序,而计数排序要准备一个用于计数的数组,对于位图,就是bit类型的数组。

在C++中,可以使用模板类bitset作为计数数组,具体实现见代码中BitmapSort_1函数。但在C语言中没有该类型的数据的,书中给出了一种用int型数据模拟bit型的操作,具体实现见下面代码中BitmapSort_2函数。

位图排序的实现,注意几点:

  1. 在使用必须确保计数数组初初始化为全0:对于用C++中模板类bitset实现的位图排序的BitmapSort_1函数,即:Bitmap.reset();对于用int型数组模拟位图的BitmapSort_2函数,即BitmapArray[1 + N/BitsPerInt] = {0};
  2. 注意语句 int BitmapArray[1 + N/BitsPerInt] = {0};   将会初始化数组所有元素,而不只是第一个;

对qsort,注意:

  1. 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]<<"\t";
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]<<"\t";
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]<<"\t";
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!\n");
192         exit(0);
193     }
194 
195     printf("file open success!\n");
196 
197     for (i = 0;i < n;i++) 
198     {
199         fprintf(fout,"%d\n",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!\n");
215         exit(0);
216     }
217 
218     printf("file open success!\n");
219 
220     for (i = 0;i < n;i++) 
221     {
222         fprintf(fout,"%d\n",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时,性能的差别更为明显。

 

posted @ 2013-07-10 20:11  永不止步,永无止境  阅读(425)  评论(0编辑  收藏  举报