算法导论-第六章堆排序

堆排序的时间复杂度为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’生成的堆是否总是一样?

    不总是一样,
    

    这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值