数据结构与算法系列——排序(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)_外部排序

参考网址

原文地址:https://www.cnblogs.com/haimishasha/p/10833074.html