外部排序总结

题目:文件存储在磁盘上,假设内存容量为m,待排序文件容量为M,M>m

步骤:

1.生成顺串
    每次读入m长度文件内容,使用内部排序,有序后输出到文件,总共生成大约M/m个中转文件
2.归并顺串
    使用M/m路的归并将M/m个文件的内容归并,步骤如下:

     产生M/m+1个缓冲区,M/m个为每个输入文件的缓冲区,一个为输出文件缓冲区,然后M/m路归并(归并过程如图所示)写入输出缓冲区,输出缓冲区满则写文件,输入缓冲区空则再次读入。一般归并不会一次对所有的中转文件归并,而是执行多次k路归并。

外部排序总结_第1张图片

分析:k路归并,每次需要比较遍历k个数选择出最小的值复杂度为O(n)


生成顺串的优化
    使用选择置换算法生成顺串可以在有限的内存下生成大概两倍于内存的顺串,因此会产生更少的待归并中转文件。

选择置换算法:

        假设:内存容量为m,待排序文件容量为M,从小到大排序
  (1)从输入文件读取容量m的内容将可用内存填满  
  (2)读入内容构建最小堆
  (3)重复以下步骤到堆大小变为0:
           a. 把根结点的数字A(即当前读入内容中的最小值)输出到文件
           b. 从输入文件中再读出一个数字B,若B比刚输出的数字A大,则将B放到堆的根节点处;//A               若B<=A,则将堆的最后一个元素移到根结点,将B放到堆的最后一个位置,并把堆的大小缩减1(即新读入的数据没有进入堆中)
         c. 在根结点处调用Siftdown重新维护堆
         //当前文件第一个输出A,后面输出的只能大于A不能小于A,因此新加入的B若<=A则不能在待输出序列,因此不进入堆,因此堆缩小将值放到堆外
         //若B>A则,B可以输出到文件中,因此放入堆中,因此先临时放置到根节点,堆不缩小    
         //最后无论B是否大于A,操作都会扰乱堆的根节点因此重新调整堆
  (4)换一个输出文件,重新回到步骤(2)

注:选择置换算法生成的各个归并段(中转文件)长度(记录数)可能不平等,以长度为权,构造一个k叉Huffman归并树(归并树代表了归并方案,不一定必须构造树)可以使外存访问次数最少,被称为最佳归并树

多路归并的优化
    k路归并,从k个数字快速得到最小的值
    ->可以组织一个堆,每次加入新元素后调整堆的时间复杂度为O(lgn),相当于O(lgn)时间复杂度内得到了最小值,k个元素的最小值lgk次比较就可以产生.
    ->胜者树,两两比较,树内部节点记录胜者,时间复杂度为O(lgn),但比堆比较次数更少
    ->败者树,内部节点记录败者,使用额外一个空间记录胜者

    堆,胜者树,败者树在产生最小值的时空复杂度量级是相同的,同一量级下胜者和败者树使用更多空间,比堆比较次数更少

你可能感兴趣的:(数据结构与算法)