选择排序和堆排序

来源:互联网 发布:有个漂亮女朋友知乎 编辑:程序博客网 时间:2024/05/29 02:32
简单选择排序和堆排序。他们都属于选择类排序。

  • 简单选择排序
    1. 每趟排序:从无序序列中选择最小(或最大)值。更具体的说,每次从无序序列中选择最小值的位置,然后和无序序列的第一个位置(有序序列临界)进行交换,这样使得有序序列的长度加1,无序序列的长度减1. 
    2. N个元素的简单选择排序需要N-1趟;不是N的原因是长度为1时自然有序,则省去了一趟排序。
    3. 从n个元素中得到最小值,需要恒定比较n-1次;第一趟排序因为无序序列长度为N,所以比较次数是N-1, 第二趟排序无序序列长度是N-1, 比较次数是N-2, 依次类推,直到无序序列的长度为1为止。

  • 堆排序
    1. 堆是一种数据结构 - 满足一定规则的完全二叉树,因此可以用数组来存储,从而父子之间可以通过下标的转换进行定位。具体的规则以大顶堆为例,1) 父节点大于等于左右子节点,2) 定义是递归的,即左右子树也分别是堆;
    2. 堆排序主要的基本思想是针对简单排序中每趟排序对n个元素的比较都需要n-1次,即每趟排序都是独立的,没有利用上一趟排序中比较的结果。堆排序主要是为了减少比较次数,基于大小比较之间的传递关系,即如果 A> B, B >C, 则 A > C, 这样则不需要A与C之间的比较,而是直接能够推论出;
    3. 堆排序主要包括 1) 初始时堆的建立,2) 以及每次输出堆顶找到最大值后,将末尾元素放入堆顶后,对其进行调整使其继续为堆。其实第一步堆的建立也是多次堆调整的过程,从第一个有子节点的节点开始从后向前直到第一个元素为止进行调整;
    4. 每趟排序是取出堆顶元素作为无序序列的最大值,和无序序列的末尾元素进行交换,然后调整堆顶元素,使其继续为堆;
    5. 一个巧妙之处是每次将堆顶元素和无序序列末尾元素进行交换,好处 1) 和有序序列临界,从而使有序序列长度加1,无序序列长度减1; 2) 无序序列的末尾元素一定不存在无序序列中的子节点,因此可以直接挪到堆顶,而不需要考虑子节点如何处置;
    6. 堆的调整操作是堆排序的核心,如前所述,无论是堆的初始化建立,还是后期的每趟排序都需要此调整操作;调整操作中,每次和左右子节点进行比较,如果发生交换,继续迭代考虑发生交换的子节点是否需要和其子节点继续进行交换,直到没有子节点或者满足大顶堆为止。因此可以看到每趟排序中比较次数最多等于无序序列的深度,而不是n-1了,数目大大减少。

0 0