• 数据结构与算法系列——排序(1)_概述


    1. 定义

      排序是将一组“无序”的记录序列调整为“有序”的记录序列。分内部排序和外部排序。

      内部排序:若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。【衡量内排序的效率是数据的比较次数】

      外部排序:若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。【衡量外排序的效率是内存与外存的交换次数】 

      内部排序的过程是一个逐步扩大记录的有序序列长度的过程。

    2. 分类

      稳定排序:假设在待排序的文件中,存在两个或两个以上的记录具有相同的关键字,在用某种排序法排序后,若这些相同关键字的元素的相对次序仍然不变,则这种排序方法是稳定的。其中冒泡,插入,基数,归并属于稳定排序,选择,快速,希尔,归属于不稳定排序。(稳定:插冒归基;  不稳定:快选堆希)
      就地排序:若排序算法所需的辅助空间并不依赖于问题的规模n,即辅助空间为O(1),则称为就地排序。
      精简排序:对一对数字不进行两次和两次以上的比较。(精简:直接插入,归并排序)

    3. 常用内部算法

    4. 外部排序算法 

    1. 实现外部排序的两个过程:

    1. 将整个初始文件分为多个初始归并段;
    2. 将初始归并段进行归并,直至得到一个有序的完整文件;

    2. 时间组成:

    1. 内部排序所需要的时间
    2. 外存信息读写所需要的时间 (关键) 
      • 与归并的趟数有关 
        • k要大 —– 传统方法 会引起内部归并时间增大 
          • 堆排序
          • 赢者树
          • 败者树(目的:提高在k个归并串中当前值中找到最小值的效率)
        • m要小 —– 置换选择排序
      • Huffman(归并的顺序,对外存的I/O次数降到最低)
    3. 内部归并所需要的时间    

    3. 为了提高整个外部排序的效率,分别从以上两个方面对外部排序进行了优化:

    1. 在实现将初始文件分为 m 个初始归并段时,为了尽量减小 m 的值,采用置换-选择排序算法(内部使用败者树实现),可实现将整个初始文件分为数量较少的长度不等的初始归并段。
    2. 同时在将初始归并段归并为有序完整文件的过程中,为了尽量减少读写外存的次数,采用构建最佳归并树的方式(哈夫曼树实现),对初始归并段进行归并(败者树实现),而归并的具体实现方法是采用败者树的方式。

    4. 优化递进顺序:

    1. 二路归并【因为硬盘的读写速度比内存要慢的多,按照以上这种方法,每个数据都从硬盘读了三次,写了三次,要花很多时间。考虑K路】
    2. 多路归并【K不是越大越好,因为K越大,在内部排序需要的时间越长,效率低。考虑减少初始顺串的数量M】
    3. 置换选择算法【可以用败者树和堆排序实现,得到多个长度不等的初始归并段,如何设置它们的归并顺序,可以使得对外存的访问次数降到最低? 考虑结合哈夫曼树】
    4. 最佳归并树(置换选择算法+哈夫曼树+多路归并+败者树)

    5 胜者树 & 败者树 & 堆排序

    发展历史

      • :其实一开始就是只有堆来完成多路归并的,但是人们发现堆每次取出最小值之后,把最后一个数放到堆顶,调整堆的时候,每次都要选出父节点的两个孩子节点的最小值,然后再用孩子节点的最小值和父节点进行比较,所以每调整一层需要比较两次。 
      • 胜者树:这时人们想能否简化比较过程,这时就有了胜者树,这样每次比较只用跟自己的兄弟节点进行比较就好,所以用胜者树可以比堆少一半的比较次数。 而胜者树在节点上升的时候首选需要获得父节点,然后再获得兄弟节点,然后再比较。
      • 败者树:这时人们又想能否再次减少比较次数,于是就有了败者树。在使用败者树的时候,每个新元素上升时,只需要获得父节点并比较即可。 
      • 所以总的来说,减少了访存的时间。 现在程序的主要瓶颈在于访存了,计算倒几乎可以忽略不计了。

    相同点

    首先它们三个的相同点就是在于:空间和时间复杂度都是一样的O(N*logN)。调整一次的时间复杂度都是O(logN)的。 
    所以这道题用堆来做,跟用败者树来做并没有本质上的算法复杂度量级上的差别。

    不同点

    • :所有的节点都是关键字; 每次调整一层需要比较两次(父亲 左孩子|  父亲 右孩子)。 
    • 胜者树:叶子节点是关键字,非叶子节点保存胜者索引;每次调整一层需要比较1次(自己 兄弟),读取两次(父亲| 兄弟)。
    • 败者树:叶子节点是关键字,非叶子节点保存败者索引;每次调整一层需要比较1次(自己 父亲),读取一次(父亲),只需要和路径上的节点比较,不需要和兄弟节点比较,简化了重构的过程。; 新增B[0]记录比赛的胜者【在本例子中是ls[0]】

    网站链接排序

    1. 数据结构与算法系列——排序(1)_概述
    2. 数据结构与算法系列——排序(2)_直接插入排序
    3. 数据结构与算法系列——排序(3)_折半插入排序
    4. 数据结构与算法系列——排序(4)_Shell希尔排序
    5. 数据结构与算法系列——排序(5)_简单选择排序
    6. 数据结构与算法系列——排序(6)_树形选择排序
    7. 数据结构与算法系列——排序(7)_堆排序
    8. 数据结构与算法系列——排序(8.1)_冒泡排序
    9. 数据结构与算法系列——排序(8.2)_鸡尾酒排序
    10. 数据结构与算法系列——排序(9)_快速排序
    11. 数据结构与算法系列——排序(10)_归并排序
    12. 数据结构与算法系列——排序(11)_基数排列
    13. 数据结构与算法系列——排序(12)_计数排序
    14. 数据结构与算法系列——排序(13)_鸽巢排序
    15. 数据结构与算法系列——排序(14)_桶排序
    16. 数据结构与算法系列——排序(15)_外部排序

    参考网址

  • 相关阅读:
    Android拍照+方形剪裁——附代码与效果图
    Caffe源代码中Solver文件分析
    Java学习笔记五(多线程)
    setTimeout和setInterval的区别
    javascript中this的妙用
    javascript基于原型的语言的特点
    css样式小技巧
    html块元素和内联元素
    怎么解决浏览器兼容性问题
    高效率、简洁、CSS代码优化原则
  • 原文地址:https://www.cnblogs.com/haimishasha/p/10833074.html
Copyright © 2020-2023  润新知