算法导论-第六章堆排序

来源:互联网 发布:unity3d 做个黑洞 编辑:程序博客网 时间:2024/06/07 08:23
堆排序的时间复杂度为O(nlgn)

数据结构

(二叉)堆是一个数组A,该数组具有两个属性

A.length:给出的是数组元素的个数A.heap-size:表示的是有多少个堆元素存储在该数组中

堆的结构可以近似的看作是一个完全二叉树,数据的元素将数组中的元素是从左至右填充为树的节点,类似于树的层次遍历的方式。
一个堆中的节点的高度为该节点到根节点(此处与教材有出入)最长简单路径上边的数目
包含n个元素的堆的高度为θ(lgn)

  • PARENT(i) return Math.floor(i/2):求下标为i的元素的父节点的下标
  • LEFT(i) return 2i:求下标为i元素的左子树的节点的下标
  • RIGHT(i) return 2i+1:求下标为i元素的右子树的节点的下标

二叉堆的两种形式

  • 最大堆

    A[PARENT(i)]>=A[i]
  • 最小堆

    A[PARENT(i)]<=A[i],通常用于构造优先队列

堆的一些基本过程

  • MAX-HEAPIFY
  • BUILD-MAX-HEAP
  • HEAPSORT
  • MAX-HEAP-INSERT、HEAP=EXTRACT-MAX、HEAP-INCREASE-KEY、HEAP-MAXIMUM,功能是利用堆实现一个有限队列
MAX-HEAPIFY(A,i)
对于一个树高为n的结点来说,MAX-HEAPIFY的时间复杂度是O(h)维护堆的性质MAX-HEAPIFY(A,i)    l = LEFT(i);    r = RIGHT(i);    if l <= A.head-size and A[i] < A[l]        largest = l;    else largest = i;    if r <= A.heap-size and A[largest] < A[r]        largest = r;    if i 不等于 largest        exchange A[largeset]和A[i]        MAX-HEAPIFY(A,largest)
BUILD-MAX-HEAP
总的时间复杂度为O(nlgn),但这个上界不是渐进紧确的,O(n)使用自底向上的方法利用过程MAX-HEAPIFY(A,i)把一个大小为n=A.length的数组A[1,,n]转换为最大堆BUILD-MAX-HEAP(A)    A.heap-size = A.length    for i = A.length / 2 downto 1        MAX-HEAPIFY(A,i)
HEAPSORT
时间复杂度为O(nlgn)以最大堆为例,每次将第一个元素与最后一个元素交换,同时将堆的大小减一HEAPSORT(A)    BUILD-MAX-HEAP(A)    for i = A.length downto 2        exchange A[1] with A[i]        A.head-size = A.head-size - 1        MAX-HEAPIFY(A,1)

优先队列

在一个包含n个元素的堆中,所有的优先队列的操作都可以在O(lgn)时间内完成
  • 最大优先队列

    应用到共享计算机系统的作业调度操作:    插入(INSERT(S,x))    取得最大值(MAXIMUM(S))    删除并返回最大值(EXTRACT-MAX(S))    将某一个元素key增大到制定的值(INCREASE-KEY(S,x,k))
    MAXIMUM(S)
    MAXIMUM(S)    return A[1]     # 返回第一个值,即最大堆的最大值
    HEAP-EXTRACT-MAX(S)
    HEAP-EXTRACT-MAX(S)    if A.heap-size < 1        error  "heap underflow"    max = A[1]    A[1] = A[A.heap-size]               # 将最后一个元素赋值给A[1],等同于删除最大值    A.heap-size = A.heap-size - 1       # 通过减少堆数组的长度来‘删除’最后一个元素    MAX-HEAPIFY(A,1)                    # 将A[1]中的元素放到恰当的位置    return max
    HEAP-INCREASE-KEY(S,x,key)
    这里要求key必须大于当前的值A[i]HEAP-INCREASE-KEY(S,x,k)    if key < A[i]        error "new key is smaller than curent key"    A[i] = key    while i > 1 and A[PARENT(i)] < A[i]     # 维护最大堆的性质        exchange A[PARENT(i)] with A[i]        i = PARENT(i)
    INSERT(S,x)
    HEAP-INSERT(S,key)    A.heap-size = A.heap-size - 1    A[A.heap-size] = -∞    HEAP-INCREASE-KEY(A,A.heap-size,key)
  • 最小优先队列

    基于事件驱动的模拟器

题目的证明

  • 在高度为h的队中,元素个数的最多和最少为多少?

  • 证明:含n个元素的堆的高度为⌊lgn⌋

思考

  • 使用插入的方法建堆

    BUILD-MAX-HEAP'(A)    A.heap-size = 1    for i = 2 to A.length        MAX-INSERT(A,A[i])

    当输入相同的时候,BUILD-MAX-HEAP和BUILD-MAX-HEAP’生成的堆是否总是一样?

    不总是一样,

    这里写图片描述