第七章(排序).pptVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第七章(排序)

* * * * 可否有其他的策略? 分析代价模型 输入: 归并过程为二叉树 子顺串为二叉树结点,长度分别为Li,与根节点距离为Hi 归并排序代价: Cost = ∑(Li×Hi) 最佳归并树 使得Cost最小 最佳归并树 把初始顺串长度作为权 最佳归并树 Huffman树! 归并过程 在k个记录中选择最小者 需要顺序比较(?)次 k-1 每趟归并u个记录需要做(?)次比较 (u-1)*(k-1)次比较 s趟归并总共需要的比较次数为: s*(u-1)*(k-1)=?logkm?*(u-1)*(k-1) =?log2m?*(u-1)* (k-1)/?log2k? K路外归并排序 为了减少归并趟数,可以 增加归并的顺串数量k s趟归并总共需要的比较次数为: s*(u-1)*(k-1)= ?log2m?*(u-1)* (k-1)/?log2k? 分析:是否K越大越好? 增大归并路数k,会使内部归并的时间增大 若k增大到一定的程度,就会抵消掉由于减少读写磁盘次数而赢得的时间 如何解决? K路归并策略 需求分析 具备归并功能 K增大,不显著增加代价 归并功能? 候选策略? 思路? 锦标赛 多路归并——选择树 k路归并是每次将k个顺串合并成一个排好序的顺串 一般情况下,对m个初始顺串进行k路归并时归并趟数为logkm 增加每次归并的顺串数量k可以减少归并趟数 选择树 完全二叉树 胜者树和败者树。 胜者树 假设用完全二叉树的公式化描述方法来定义胜者树,采用数组作为存储结构。 选手或叶结点用数组L[1...n]表示,内部结点用数组B[1...n-1]表示 数组B中实际存放的是数组L的索引(下标) 胜者树的一个优点 如果一个选手L[i]的分数值改变了,可以很容易地修改这棵胜者树。只需要沿着从L[i]到根结点的路径修改二叉树,而不必改变其它比赛的结果 胜者树 8路合并的胜者树 胜者树 重构后的胜者树 胜者树 分析: 除去叶结点层,树的层数为?log2(k + 1)? 重构树的时间为O(log2k) 对于每一个归并到输出文件的记录都需要重构树 归并n个记录的时间是O(n log2k) 建立初始胜者树的时间是O(k) 归并k个归并段的总时间是O(n log2k) 胜者树 特点 比赛是在兄弟结点之间进行 结果存放在它们的双亲结点中 新一轮比赛在下一个更靠近根的层次进行 可否改进? L R New Data 败者树 败者树是胜者树的一种变体 在败者树中 用父结点记录其左右子结点进行比赛的败者 让获胜者去参加更高阶段的比赛 根结点处加入一个结点来记录整个比赛的胜者 采用败者树是为了简化重构的过程 比较在父子节点之间进行 败者树 重构过程如下: 将新进入选择树的结点与其父结点进行比赛 把败者的下标存放在父结点中 而胜者再与上一级的父结点比较 比赛沿着到根结点的路径不断进行,直到结点B[1]处 把败者的索引放在结点B[1] 把胜者的索引放到结点B[0] 败者树 8路合并的败者树示例 败者树 重构后的8路合并败者树 败者树 class LoserTree { public: LoserTree(int k); // 构造函数 void Build( ); // 建立初始败者树 … // 其它操作 private: int k; int *l; // 非叶结点 Rec *buf; // 记录缓冲区 int getKey(int i); // 返回结点i指向的记录缓冲区中的关键字 int getIndex(int i); // 返回结点i存放的记录缓冲区指针 }; 构造函数 LoserTree::LoserTree(int k) { l = new int[k]; // 非叶结点空间 buf = new Rec[k]; // 记录缓冲区空间 } void LoserTree::Build( ) { // 假设记录缓冲区已输入数据 int i; // 自下而上建立胜者树 for (i = k – 1; i 0; i--) if (getKey(2*i) getKey(2*i + 1) l[i] = getIndex(2*i + 1); else l[i] = getIndex(2*i); l[0] = l[1]; // 总胜者 // 自上而下建立败者树 for (i = 1; i k; i++) if (l[i] == getIndex(2*i) l[i] = getIndex(2*i + 1);

文档评论(0)

xy88118 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档