外部排序~

被面试官问了个对数组求交集,但是内存只能装载一个数组。然后想到数据结构的外部排序,但是当时没去看,现在补一下

对于这个面试问题的个人解法,可能不对,欢迎交流

  • 先对两个数组用外部排序.使得有序
  • 然后分别对两个有序数组掉一部分到内存,然后进行求交集,对两个有序数组求交集用双指针即可,具体实现自行了解

朋友的解法 感觉很妙!!!

  • 将数组记录各自哈希到文件,用各自数组同哈希值的文件进行求交集,如果文件过大进行rehash

外部排序

基本方法

  • 1.将外存n个记录分成若干长度为l的子文件或段,依次读入内存,利用有效的内部排序对其进行排序
  • 2.将排序后得到的有序子文件重新写入外存 得到 m个归并段
  • 3.对归并段进行多路归并

优化与分析

  • 归并趟数: l o g k m {log_k{m}} logkm

  • 普通K路归并段归并 每次取出一个最小元素要比较 k - 1 次,n个记录的内部归并段需要(n - 1) * (k - 1)

  • 内部归并比较次数 ( k − 1 ) ( n − 1 ) l o g k m (k - 1)(n - 1){log_k{m}} (k1)(n1)logkm

  • 多路平衡归并:将每次取出一个最小元素花的时间优化为 l o g 2 k {log_2{k}} log2k

  • 使用败者树,叶子节点是归并段,值小的是胜利者,先调整,之后取出冠军,在从冠军对应的段中拿出新的数据(为了保证每个段都不空,给每个段尾加一个最大关键字,当冠军是最大关键字,说明已经归并完了)

  • 于是K路归并比较次数 ( n − 1 ) l o g 2 m (n - 1){log_2{m}} (n1)log2m

继续优化:减少m的大小

  • 置换-选择排序
  • 内排得到的归并段数目取决于工作区域大小 m = n/l,n为记录数,l为工作区可以装载的记录个数
  • 为了减少归并段m,于是有了 置换-选择排序算法 来得到我们的归并段,原理是把做排序的时候把工作区拿来当类似缓冲的东西,通过败者树把原记录的文件有序的归并到多个其他文件。具体实现自行查阅.可以证明数据是随机数时,得到归并段平均长度是 内存工作区 w 的两倍,则归并段数目减半。通过扫雪机证明可以得到生成所有归并段时间复杂度是 O n l o g 2 w O{nlog_2{w}} Onlog2w

新的问题:置换-选择生成所得到的初始归并段,各个段长度不等对平衡归并的影响

  • 解决:构造一棵哈夫曼树作为归并树(哈夫曼树:权值越大的结点离根结点越近,带权路径长度最短–>归并比较次数最小)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值