Ⅱ.Sorting and Order Statistics 1.Heapsort

Ⅱ.Sorting and Order Statistics

Introduction

这一部分将着重介绍排序问题的算法:

输入:一个n个数的序列 < a 1 , a 2 , . . . , a n > <a_1,a_2,...,a_n> <a1,a2,...,an>

输出:输入序列的一个排列(重排) < a 1 ′ , a 2 ′ , . . . , a n ′ > <a_1',a_2',...,a_n'> <a1,a2,...,an>,使得 a 1 ′ ≤ a 2 ′ ≤ . . . ≤ a n ′ a_1'\leq a_2'\leq...\leq a_n' a1a2...an

输入通常是一个n元素的数组,但是可能是用链表等方式描述。

在实际应用中,待排序的数很少是单独的数值

在这里插入图片描述

Heapsort

时间复杂度是 O ( n l g n ) O(nlgn) O(nlgn)。相同于插入排序的是,堆排序同样具有空间原址性:任何时候都只需要常数个额外的元素空间存储临时数据。

Heaps

  • 近似于完全二叉树

  • 堆的数组包括两个属性,length给出数组元素的个数,heap-size给出在数组中有多少个有效的堆元素;

    因此在堆数组A中,可能A[1…A.length]都有数据,但只有A[1…heap-size]中存放的堆的有效元素

  • 堆的根节点是A[1]

  • 父节点 P a r e n t ( i )   r e t u r n ⌊ i / 2 ⌋ Parent(i)\ return \lfloor i/2\rfloor Parent(i) returni/2 右移一位

    左节点 L E F T ( i )   r e t u r n   2 i LEFT(i)\ return\ 2i LEFT(i) return 2i 左移一位

    右节点 R I G H T ( i )   r e t u r n   2 i + 1 RIGHT(i)\ return \ 2i+1 RIGHT(i) return 2i+1 左移一位并加一

  • 二叉堆有两种情况,最大堆和最小堆

  • 最大堆:除根节点外,所有的结点i满足 A [ P a r e n t ( i ) ] ≥ A [ i ] A[Parent(i)]\geq A[i] A[Parent(i)]A[i]

    最小堆同理

  • 定义高度为该节点到叶节点的最长简单路径长度

  • 堆的高度为 θ ( l g n ) \theta(lgn) θ(lgn),堆上的基本结构花费的时间最多为 O ( l g n ) O(lgn) O(lgn)

维护堆的性质

这一部分我们着重介绍堆的一些基本操作

MAX-HEAPIFY(A,i)

保证最高处最大

A[i]有可能小于其孩子,这个就是一个修复的过程

在这里插入图片描述

进行交换的时间代价为 θ ( 1 ) \theta(1) θ(1),而子树的大小至多为2n/3(最坏的情况发生在树的最底层恰好半满的情况),那么运行时间的表达式为:
T ( n ) ≤ T ( 2 n / 3 ) + θ ( 1 ) T(n)\leq T(2n/3)+\theta(1) T(n)T(2n/3)+θ(1)
解得递归式的解为 T ( n ) = O ( l g n ) T(n)=O(lgn) T(n)=O(lgn),这里建议不能一下子得到解的同学返回第一章复习,课后题都要做的呀。

建堆

子数组 A ( ⌊ n / 2 ⌋ + 1.. n ) A(\lfloor n/2\rfloor+1..n) A(n/2+1..n)中的元素都是叶节点,或者说我们有这么多叶节点,没必要调用这些数量的结点,他们都在底层,没有后代与之交换

利用MAX-HEAPIFY把一个大小为A.length的数组转换为最大堆

在这里插入图片描述

n次调用,每次logn,因此时间复杂度是 O ( n l g n ) O(nlgn) O(nlgn),但是这个上界虽然正确,但不是渐进紧确的。

下面证个渐进的:

  • 堆的每层最多包含 ⌈ n / 2 h + 1 ⌉ \lceil n/2^{h+1}\rceil n/2h+1个结点

又MAX-HEAPIFY的代价是 O ( h ) O(h) O(h),我们可以将BUILD-MAX-HEAP的总代价表示为:

在这里插入图片描述

等价为:

在这里插入图片描述

线性时间足以建一个最大堆

类似的,我们得到最小堆算法

堆排序算法

不断从尾部向头部调用

在这里插入图片描述

时间复杂度为 O ( n l g n ) O(nlgn) O(nlgn)

Priority queue

一种用来维护由一组元素构成的集合S的数据结构,其中的每一个元素都有一个相关的值,称为关键值(key)。最大优先队列支持一下操作:

  1. INSERT(S,x):把元素x插入集合S中。这一种操作等价于 S = S ⋃ { x } S=S\bigcup \{x\} S=S{x}
  2. MAXIMUM(S):返回S中具有最大关键字的元素
  3. EXTRACT-MAX(S):去掉并返回S中的具有最大关键字的元素
  4. INCREASE-KEY(S,x,k):将元素x的关键字值增加到k,这里的k值默认不小于x的原关键字值

最大优先队列可以用来共享计算机系统的作业调度,当一个作业完成或被中断后,选出具有最高优先级的作业来执行

最小优先队列可以被用于事件驱动的模拟器。具体看以后内容吧。

比如事件驱动模拟器中,优先队列的元素对应着应用程序中的对象。通常,我们需要确定哪个对象对应一个给定的优先队列元素,因此,用堆来实现优先队列是,需要在堆中的每个元素里存储对应对象的句柄。

接下来我们还是来了解一些基础操作的实现吧:

在这里插入图片描述

复杂度为 θ ( 1 ) \theta(1) θ(1)

在这里插入图片描述

时间复杂度为 O ( l g n ) O(lgn) O(lgn)

在这里插入图片描述

时间复杂度为 O ( l g n ) O(lgn) O(lgn),因为在最底层更新到根节点的路径长度为 O ( l g n ) O(lgn) O(lgn)

在这里插入图片描述

在包含n个元素的堆上,MAX-HEAP-INSERT的运行时间为 O ( l g n ) O(lgn) O(lgn)时间内完成。

#################################################
拖了好久才更新,到了假期按理说变闲了,但是要学的东西实在不少啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值