读《Programming Pearls,编程珠玑》开篇后总结的文件排序笔记,主要是笔记“位图数据结构的使用”和“多通道排序”算法。
1 文件排序的思路
- 调用磁盘排序的库函数。
- 主存排序。
- 利用位图数据结构或多通道实现算法。
2 主存较小时的排序方法
虽然位于现今儿这个时代里,主存都是以G为单位标识了。但难免会出现《编程珠玑》开篇中所叙述的那样,一个大系统将主存占用的只有少许了,然后这个时候还要对超过主存许多的文件排序。正如书中所述,此时再调用库函数来进行磁盘排序的方法是行不通的,故而作者别出心裁想到了另外的一些方法。
(1) 位图数据结构
位图数据结构:它可以被看成一个字符数组。用数组元素的0和1的状态来记录文件中的元素。如文件中包含| 1, 3, 7, 9 |则定义位图数据结构char bit[10](数组下标是文件的范围上限加1),并通过读文件中的数据将bit[1], bit[3], bit[7], bit[9]元素赋值为1,bit数组的其余元素全都为0。这样就用bit数组的下标标识了文件中的数为1,3,7,9即只要当前数组元素的值为1,则下标值就是文件中的数。
例子:文件file中有范围为1 ~ 1000000的32位不重复整数,主存因某种原因还剩下2M。现需编写程序来对file排序,该如何编程?
伪码:
char bit[N+1] for i = [0,N] bit[i] = 0 for each i in the file bit[i] = 1 for i =[0, N] if bit[i] == 1 write to outputfile |
(2) 多通道
例子:若上个例子中主存只有1M时再对文件整数进行排序。
伪码:
DN = 125000, j = 0 for i = [0, n) //n为读文件的次数 for each data from file if DN * i <= data < DN *(i + 1) a[j++] = data qsort(a) //排此次范围的数 for each i in a write to outputfile |
这样,程序每次从文件中读取的数据为DN * i ~ DN *(i + 1)到主存中,随着i的增加,上一次读入的数据都小于当前次读取的数据,故而只要将每次读取到的数据排序后依次输出到文件中就自然让源文件file中的数据有序了。
(3) 位图数据结构排序和多通道排序的总结
位图数据结构使用步骤总结
- 明确文件的数据范围如0 ~ N以定义位图数据结构char bit[N+1],并初始化bit数组元素都为0。
- 从文件中读取数据,每读一个数据i就将bit[i]置为1。
- 处理bit数组元素值为1的下标即文件中的数据。
多通道与位图数据结构的比较
- 位图数据结构占用内存约为数据的个数(若数不连续则为最大的那个数加1)字节,多通道程序数据所占内存的大小可被调(读的次数越多每次所占内存越小)。位图数据结构程序时间复杂度O(N),多通道为O(N*n),位图数据结构代码更简单。
- 位图数据结构还可以用于查找等用途。
Small Box Note Over。