位图排序 收藏


问题:

给定输入文件,文件中每条记录是一个整型数(不重复),每条记录最大为n,n<=10000000,要求对文件中所有记录排序(从小到大),然后输入到给定文件。

限制:主存不超过1MB(实际程序超过了1M)。

按照《编程珠玑》上介绍,有以下几种方法:

1,多通道分片读取文件,然后合并排序分片文件

2,位图排序:适合于对大量不重复数据,并且数据其他相关数据。

算法描述如下:

示例:对于不超过20的整型数据,可以用20个bit位来表示,例如1,2,4,14可表示:

00000010000000001011,即将每一个数对应的bit位置1。

因此,对于10000000个记录项,可以用10000000个bit位来表示。

在设置或清除每一个读取的整数对应的位时:

(1)首先找到该整数对应的数组的下标(i>>5)。由于数组中的每一个整数有32位(假设int型为32位),这32位可以表示32个整数。

(2)找到该整数在对应整数的位坐标pos。

(3)设置或清除该整数的位。

c++实现如下:view plaincopy to clipboardprint?
1 #include <iostream>
2 #include <bitset>
3 #include <fstream>
4 #include <vector>
5 using namespace std;
6 const int BITSPERWORD=32;
7 const int MAX = 100000;
8 const int NUM = MAX/BITSPERWORD;
9 vector< bitset<32> > vec(1+NUM);
10 void set(int i )
11 {
12 /*
13 int tmp = i>>5;
14 cout << tmp <<endl;
15 */
16 vector<bitset<32> >::iterator it = vec.begin();
17 int pos = i%32;
18 it += i>>5;
19 (*it).set(pos,1);
20 }
21 void clear(int i)
22 {
23 vector<bitset<32> >::iterator it = vec.begin();
24 int pos = i%32;
25 it += i>>5;
26 (*it).reset(pos);
27 }
28 int test(int i)
29 {
30 vector<bitset<32> >::iterator it = vec.begin();
31 int pos = i%32;
32 it += i>>5;
33 if((*it).test(pos))
34 return 1;
35 else
36 return 0;
37
38 }
39 int main()
40 {
41 ifstream fin("source.file");
42 ofstream fout("sort.file");
43 int i = 0;
44 int tmp = 0;
45
46 vector< bitset<32> >::iterator it = vec.begin();
47 while(it!=vec.end())
48 {
49 (*it).reset();
50 //cout << (*it)<<endl;
51 it++;
52 }
53 /*
54 for(i = 0;i<NUM +1;i++)
55 clear(i);
56 */
57 while(fin>>tmp)
58 {
59 set(tmp);
60 }
61 for(i = 0;i<MAX+1;i++)
62 if(test(i))
63 fout<< i << endl;
64 }
1 #include <iostream>
2 #include <bitset>
3 #include <fstream>
4 #include <vector>
5 using namespace std;
6 const int BITSPERWORD=32;
7 const int MAX = 100000;
8 const int NUM = MAX/BITSPERWORD;
9 vector< bitset<32> > vec(1+NUM);
10 void set(int i )
11 {
12 /*
13 int tmp = i>>5;
14 cout << tmp <<endl;
15 */
16 vector<bitset<32> >::iterator it = vec.begin();
17 int pos = i%32;
18 it += i>>5;
19 (*it).set(pos,1);
20 }
21 void clear(int i)
22 {
23 vector<bitset<32> >::iterator it = vec.begin();
24 int pos = i%32;
25 it += i>>5;
26 (*it).reset(pos);
27 }
28 int test(int i)
29 {
30 vector<bitset<32> >::iterator it = vec.begin();
31 int pos = i%32;
32 it += i>>5;
33 if((*it).test(pos))
34 return 1;
35 else
36 return 0;
37
38 }
39 int main()
40 {
41 ifstream fin("source.file");
42 ofstream fout("sort.file");
43 int i = 0;
44 int tmp = 0;
45
46 vector< bitset<32> >::iterator it = vec.begin();
47 while(it!=vec.end())
48 {
49 (*it).reset();
50 //cout << (*it)<<endl;
51 it++;
52 }
53 /*
54 for(i = 0;i<NUM +1;i++)
55 clear(i);
56 */
57 while(fin>>tmp)
58 {
59 set(tmp);
60 }
61 for(i = 0;i<MAX+1;i++)
62 if(test(i))
63 fout<< i << endl;
64 }

c语言实现如下:

view plaincopy to clipboardprint?
1 #include <stdio.h>
2
3 #define MAX 100000
4 #define BITSPERWORD 32
5 #define NUM (MAX/BITSPERWORD)
6
7 int a[NUM+1];
8 void set(i)
9 {
10 int label;
11 int pos;
12 label = i>>5;
13 pos = i%32;
14 // pos = i&0x1f;
15 a[label] |= 1<<pos;
16 }
17 void clear(i)
18 {
19 int label;
20 int pos;
21 label = i>>5;
22 pos = i%32;
23 //pos = i&0x1f;
24 a[label] &= ~(i<<pos);
25 }
26 int test(i)
27 {
28 int label;
29 int pos;
30 label = i>>5;
31 // pos = i&0x1f;
32 pos = i%32;
33
34 if(a[label]&(~(1<<pos)))
35 return 1;
36 else
37 return 0;
38 }
39 int main()
40 {
41
42 FILE *fin;
43 FILE *fout;
44 fin = fopen("source.file","r");
45 fout = fopen("sort.file","w");
46 int i = 0;
47 for(i = 1;i<MAX+1;i++)
48 clear(i-1);
49 int tmp;
50 while(fscanf(fin,"%d",&tmp)!=EOF)
51 {
52 set(tmp-1);
53 }
54 for(i = 1;i<MAX+1;i++)
55 {
56 if(test(i-1))
57 {
58 fprintf(fout,"%d/n",i);
59 }
60 }
61 }
1 #include <stdio.h>
2
3 #define MAX 100000
4 #define BITSPERWORD 32
5 #define NUM (MAX/BITSPERWORD)
6
7 int a[NUM+1];
8 void set(i)
9 {
10 int label;
11 int pos;
12 label = i>>5;
13 pos = i%32;
14 // pos = i&0x1f;
15 a[label] |= 1<<pos;
16 }
17 void clear(i)
18 {
19 int label;
20 int pos;
21 label = i>>5;
22 pos = i%32;
23 //pos = i&0x1f;
24 a[label] &= ~(i<<pos);
25 }
26 int test(i)
27 {
28 int label;
29 int pos;
30 label = i>>5;
31 // pos = i&0x1f;
32 pos = i%32;
33
34 if(a[label]&(~(1<<pos)))
35 return 1;
36 else
37 return 0;
38 }
39 int main()
40 {
41
42 FILE *fin;
43 FILE *fout;
44 fin = fopen("source.file","r");
45 fout = fopen("sort.file","w");
46 int i = 0;
47 for(i = 1;i<MAX+1;i++)
48 clear(i-1);
49 int tmp;
50 while(fscanf(fin,"%d",&tmp)!=EOF)
51 {
52 set(tmp-1);
53 }
54 for(i = 1;i<MAX+1;i++)
55 {
56 if(test(i-1))
57 {
58 fprintf(fout,"%d/n",i);
59 }
60 }
61 }

在我的机器上测试两种语言实现的效率:测试的数据位100000,c++用时为c语言的约两倍。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/clearriver/archive/2009/07/19/4361469.aspx

你可能感兴趣的:(排序)