您的位置:首页 > 其它

排序算法总结之位排序(一)

2014-03-31 22:04 225 查看
最近在看一本计算机经典著作《编程珠玑 第2版》,第一章开篇谈到怎样在内存有限的情况下给一个磁盘文件排序,文中使用到了位向量来解决此问题,本人菜鸟觉得此方法很经典,遂在此总结一下,方便日后查阅。

所谓位排序,即是将位向量中的每一位与一个待排序的整数相关联,位向量中待排序整数值的位置1,位向量的位数大于等于待排序整数的最大值,如:要对13, 9, 15, 8, 3,,12,7进行排序,则可以使用一个16位的位向量1011 0011 1000 1000来对这些要排序的整数进行标识,即:第3位(从0开始)的1代表要排序的整数3,第7位的1代表待排序的整数7....。标识完后,然后通过一个迭代对位向量的每一位(从左到又,或从右到左)进行判断,如果为1,即输出当前的迭代值(即为待排序的整数值),迭代完成后输出的序列即为排序后的序列。

要实现位排序,需要以下三个步骤:

1、首先实现一个位向量;

2、将待排序整数序列映射到位向量;

3、迭代判断位向量的每一位(从左到右或从右到左),如果为1,则输出当前迭代值(即为待排序的整数值)。

1、位向量的实现:

即实现位向量的置位、清零、判断这3个操作。

/--------------------------------------------------------.h 文件------------------------------------------------------------------------------------------/

#ifndef _CBITMAP_H_
#define _CBITMAP_H_

#define BITPERWORD 32							//	本例使用整形数组实现位向量,整形占4byte=32bit
#define SHIFT	   5							//	判断当前要置位或清零的位位于哪个数组中,即确定数组的下标
#define MASK	   0x1F							//	置位清零掩码,cpp文件中将对将对该掩码进行说明

class CBitMap
{
// construct、deconstruc
public:
CBitMap(unsigned int BitNum);
~CBitMap();

public:
int *a;								//	位向量指针

public:
void set(int i);						//	位向量第i位置1
void clr(int i);						//	位向量第i位清0
bool test(int i);						//	位向量第i位是否为1,是,返回TRUE,否,返回FALSE
};

#endif


/-----------------------------------------------------------------------------------------.cpp文件-----------------------------------------------------------------------------------------------------/

#include "stdafx.h"
#include <memory>
#include "CBitMap.h"
// 	BitNum: 待排序整数的最大值
CBitMap::CBitMap(unsigned int BitNum)
{
a = new int [BitNum/BITPERWORD + 1];	//	将整形数组看成一个位向量 假设待排序的整数的最大值为100,则100/32+1 = 4,即用数组a[4](共128位)即						可表示所有待排序的整数,其中a[0]代表低32位,a[1]代表次低32位,a[2]代表次高32位,a[3]代表高32位。
}

CBitMap::~CBitMap()
{
delete []a;
a = NULL;
}
//	将位向量第i位置1
void CBitMap::set(int i)
{
a[i>>SHIFT] |= (1<<(i&MASK));		//	i>>SHIFT===> i>>5 <===> i/32,即判断第i位在数组中的下标。i&MASK===>i&0x1f <===> i%32,如:i=25,则
i&0x1f = 0001 1001 = 25,当i<=31时,i&0x1f=i,当i>31则进入数组下一个小标。
}

void CBitMap::clr(int i)
{
a[i>>SHIFT] &= ~(1<<(i&MASK));
}

bool CBitMap::test(int i)
{
return a[i>>SHIFT]&(1<<(i&MASK));
}


/---------------------------------------------------------------------------------主程序------------------------------------------------------------------------------------------/

/**************************************************************************************************************************************************
*									位向量排序
*1、适用场合:(1)输入数据限制在相对较小的范围内;
*	      (2)数据没有重复;
*             (3)除了单一整数外,没有任何其他关联数据。
*2、实现功能:将一个给定文件中的0~1000 0000以内的800 0000个随机的互不相等的整数按序输出。
*3、实现步骤:(1)随机生成0~1000 0000以内的800 0000个随机的互不相等的整数,并写入文档中;
*             (2)位向量的实现;(置位、清零、测试)
*             (3)读入文档,输出排序后的文档;
***************************************************************************************************************************************************/

#include "stdafx.h"
#include "CBitMap.h"
#include <fstream>
using namespace std;

#define N 10000000

int _tmain(int argc, _TCHAR* argv[])
{
CBitMap BitMap(N);							//	实例化一个位向量(位数为N)
ifstream ifs("data.txt");						//	实例化一个输入文件流对象,并与data.txt关联
ofstream ofs("dataSorted.txt");						//	实例化一个输出文件流对象,并与data.txt关联
int i = 0, data = 0;

for(i=0; i<N; i++)							//	位向量初始化(每位为0)
BitMap.clr(i);

while(ifs.good())							//	检查文件I/O操作是否异常((badbit, eofbit or failbit)
{
ifs>>data;							//	从文件流对象读取一个数据
BitMap.set(data);						//	将位向量中相应的位置1(eg:data=211, 则将第211位置1)
}
ifs.close();								//	文件读取完毕后关闭文件

for(i=0; i<N; i++)
{
if(BitMap.test(i))						//	从小到大输出位向量为1的位的位置,即从小到大排列data.txt中的数
ofs<<i<<endl;
}
ofs.close();

return 0;
}


data.txt

267 242
25 153
149 16
227 278
147 73

166 61
229 287
68 113
243 163
216 225

185 186179
19479
34 250
8 140162

217 54
63 156
7 241 95142
264112

83 19 215173
71 284
182 265
274 143

59 236
121 14
76 270
206 187
100 210

167 11
290 191
152 1 102134
150281

96 124
58 223
200 26
172 86
292 282

188 239
271 82
145 131
137 120
75 181

87 154
24 203
256 161
115 109
234 48

174 226
13 2 12629
285 232
28 222

17 158
35 169
51 273
5 66 20798

93 272
70 62 16874
81 6
9 246

253 40
104 53132
94 32
248 133
240

55 238
297 25123
204 171
31
105266

datasorted.txt

1 2
5 6 78
9 11
13 14

16 17 1923
24 25
26 2829
31

32 34 3540
48 51
53 5455
58

59 61 6263
66 68
70 7173
74

75 76 7981
82 83
86 8793
94

95 96 98100
102104
105109
112113

115 120
121 124
126 131
132 133
134 137

140 142
143 145
147 149
150 152
153 154

156 158
161 162
163 166
167 168
169 171

172 173
174 179
181 182
185 186
187 188

191 194
200 203
204 206
207 210
215 216

217 222
223 225
226 227
229 232
234 236

238 239
240 241
242 243
246 248
250 251

253 256
264 265
266 267
270 271
272 273

274 278
281 282
284 285
287 290
292 297
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: