《编程珠玑》——学习历程之一(利用位图(位矢量)的思想实现神奇排序)

当要对一个拥有千万级数据记录的电话号码文件进行排序时,我们解决问题的思路应该如下:


1.准确的问题描述:

输入:一个最多包含n个正整数的文件,每个数都小于n,n=10^7。如果在输入文件中有任何整数重复出现就是致命错误,且没有其他的数据与该整数相关联。

输出:按升序排列的输入整数的序列

约束:最多有1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需进一步优化了。



2.程序设计:

现有以下两种简单排序方式:



但实际上,我们会发现两种方式都各有缺陷,第一种方式会多次与工作文件进行交互,而多趟排序则要将输入文件进行多次操作。

因此,我们考虑用一种神奇排序,实现两种排序的优点,取长补短。

如图:



3.实现概要:

由此,我们可以使用位图位向量表示集合。

可用一个20位长的字符串来表示一个所有元素都小于20的简单的非负整数集合。例如,集合{1,2,3,5,8,13}:

0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0

代表集合中数值的位都置为1,其他所有的位都置为0。


注:

这种实现方式取决于该程序的特殊性:

输入数据限制在相对较小的范围内;数据没有重复;而且对于每条记录而言,除了单一整数外,没有任何其他关联数据。(然而实际上和三个属性在排序问题中是不常见的)


所以,我们可以利用上述方式去表示我们的数据记录。

分为三个阶段实现:

第一:将所有位置为0,即初始化集合为空。

第二:通过读入文件中的每个整数来建立集合。

第三:检验每一位,如果该位为1,就输出对应的整数,由此产生有序的输出文件。


伪代码:
/* phase 1: initialize set to empty*/

for i=[0,n)

bit[i]=0

/* phase 2:insert present elements into the set */

for each i in the input file

bit[i]=1

/* phase 3:write sorted output */

for i=[0,n)

if bit[i]=1

write i on the output file


C代码实现:

#include<stdio.h>
int main()
{
	int n=100;
	int a[5]={1,3,99,50,33},b[100]={0};
	//	phase 2:insert present elements into the set	//
	for(int j=0;j<5;j++)
	{
		b[a[j]]=1;
	}
	//	phase 3:get the output		//
	for(int i=0;i<n;i++)
	{
		if(b[i]==1)
			printf("%d\n",i);
	}
		return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值