《算法导论》第六章 堆排序 笔记

本文详细介绍了堆排序算法,包括最大堆和最小堆的概念、堆的基本操作如MAX-HEAPIFY及BUILD-MAX-HEAP,堆排序的具体实现过程,并探讨了如何使用堆实现优先队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆排序

堆排序不同于归并排序的是,堆排序具有和插入排序一样的空间原址性,任何时候都只需要常数个额外的元素空间存储临时数据。因此,堆排序是集合了插入排序和归并排序两种算法优点的排序方法。

6.1 堆

(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树。树上的每一个结点对应数组中的一个元素,除了最底层,该树是完全充满的,而且是从左到右填充。给定下面三个函数(这里计算左右孩子的方式说明数组是从1开始编号的,即A[1, A.heap_size],如果是A[0, A.heap_size-1]的话,则左右孩子的索引应该是2*i+1, 2*i+2),在堆排序的好的实现中,这三个函数通常是以“宏”或者“内联函数”的方式实现的:

PARENT(i)
    return i/2
LEFT(i)
    return 2*i
RIGHT(i)
    return 2*i+1

二叉堆有两种形式,最大堆和最小堆。两个堆都是通过父子元素的关系确定的。对于这两种形式,我们能且仅能确定的是根元素分别是数组中的最大值和最小值,这也是堆排序的基础。

一个堆中结点的高度是该结点到叶结点最长简单路径上边的数目。下面几个是堆排序中的基本过程。

  • MAX-HEAPITY: 其时间复杂度为O(lgn), 它是维护最大堆性质的关键。
  • BUILD-MAX-HEAP: 具有线性时间复杂度,功能是从无序的输入数据数组中构造一个最大堆。
  • HEAPSORT: 其时间复杂度为O(nlgn),功能是对一个数组进行原址排序。
  • MAX-HEAP-INSERT/HEAP-EXTRACT-MAX/HEAP-INCREASE-KEY/HEAP-MAXIMUM: 时间复杂度为O(nlgn),功能是利用堆实现一个优先队列。

6.2 维护堆的性质

MAX-HEAPITY(A, i)
    l=LEFT(i)
    r=RIGHT(i)
    if l<=A.heap_size and A[l]>A[i]
        largest=l
    else
        largest=i
    if r<=A.heap_size and A[r]>A[i]
        largest=r
    if largest!=i
        exchange A[i] with A[largest]
        MAX-HEAPITY(A, largest)

6.3 建堆

我们可以用自底向上的方法利用过程MAX-HEAPITY把一个大小为n=A.length的数组A[1, n]转换为最大堆。

BUILD-MAX-HEAP(A)
    A.heap_size=A.length
    for i=A.length/2 downto 1
        MAX-HEAPITY(A, i)

这里的循环不变量是:在第2~3行中每一个for循环开始的地方,结点i+1, i+2, …, n都是一个最大堆的根结点。

6.4 堆排序算法

HEAPSORT(A)
    BUILD-MAX-HEAP(A)
    for i=A.length downto 2
        exchange A[i] with A[1]
        A.heap_size=A.heap_size-1
        MAX-HEAPITY(A, 1)

6.5 优先队列

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

  • INSERT(S, x): 把元素x插入集合S中。
  • MAXIMUM(S): 返回S中具有最大关键字的元素。
  • EXTRACT-MAX(S): 去掉并返回S中的具有最大关键字的元素。
  • INCREASE-KEY(S, x, k): 将元素x的关键字值增加到k,这里假设k的值不小于x的原关键字值。

    MAXIMUM(A)
         return A[1]
    
    HEAP-EXTRACT-MAX(A)
        if A.heap_size<1
            error "heap underflow"
        max=A[1]
        A[1]=A[A.heap_size]
        A.heap_size=A.heap_size-1
        MAX-HEAPITY(A, 1)
        return max
    
    HEAP-INCREASE-KEY(A, i, key)
        if key<A[i]
            error "new key is smaller than current key"
        A[i]=key
        while i>1 and A[PARENT(i)]<A[i]
            exchange A[i] with A[PARENT(i)]
            i=PARENT(i)
    
    MAX-HEAP-INSERT(A, key)
        A.heap_size=A.heap_size+1
        A[A.heap_size]=-inf
        HEAP_INCREASE_KEY(A, A.heap_size, key)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值