堆与堆排序

  1. 如下图所示,(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树。
    堆
    堆的数组存储形式

    ○ 树上的每一个结点对应数组中的一个元素。
    ○ 除了最底层外,该树是完全充满的,而且是从左向右填充。
    ○ 上图以二叉树和数组形式展现的一个最大堆。每个结点圆圈内部的数字是它所存储的数据。结点上方的数字是它在数组中相应的下标。数组上方和下方的连线显示的是父-子关系:父结点总是在它的孩子结点的左边。该树的高度为3,下标为4(值为8)的结点的高度为1
    ○ 表示堆的数组A包括两个属性:A.length(通常)给出数组元素的个数,A.heap-size表示有多少个堆元素存储在该数组中。
    ○ 设A[1…A.heap-size…A.length],(根为A[1]),我们很容易得到给定结点i,它的父、左右子结点:

    PARTENT(i)
        return i/2;
    LEFT(i)
        reutrn 2*i;
    RIGHT(i)
        return 2*i+1;
    
  2. 二叉堆的两种形式以及性质
    ○ 最大堆

    § 除了根以外的所有结点i,都要满足:
    A[PARTENT(i)] >= A[i]

    ○ 最小堆

    § 除了根以外的所有结点i都有:
    A[PARTENT(i)] <= A[i]

  3. 堆排序中使用的是最大堆,最小堆通常用于构造优先队列。
    ○ 若某一属性既适合最大堆也适合最小堆,则使用“堆”这一名词

  4. 基本过程
    ○ MAX-HEAPIFY(A, i):维护最大堆性质的关键,时间复杂度O(lgn)

    § 假定根结点为LEFT(i)和RIGHT(i)的二叉树都是最大堆
    § 使以i为根结点的子树重新遵循最大堆的性质
    § 通过让A[i]的值在最大堆中“逐级下降”实现

    MAX-HEAPIFY(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[largest] 
            largest = r 
        if largest
    

    ○ BUILD-MAX-HEAP:从无序的输入数据数组中构造一个最大堆

    § 子数组A(n/2+1…n)中的元素都是树的叶结点(以它们作为根的子树也就是最大堆)
    § 对树中的其他结点都调用一次MAX-HEAPIFY来构建一个最大堆

    BUILD-MAX-HEAP(A)
        A.heap-size = A.length
        for i = A.length/2 downto 1
      		MAX-HEAPIFY(A, i)
    

    ○ HEAPSORT:对一个数组进行原址排序

    § BUILD-MAX-HEAP将输入的数组A[1…n]建成最大堆
    § 最大的元素总在根A[1],把它与A[n]交换,并去掉结点n(A.heap-size减1即可)
    § 此时新的根A[1]可能不是最大堆,因此调用MAX-HEAPIFY(A,1)来维护最大堆性质
    § 不断重复上述操作(直到堆只剩下一个元素),最终数组上的值按从小到大排序好。

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

    ○ MAX-HEAP-INSERT
    ○ HEAP-EXTRACT-MAX
    ○ HEAP-INCREASE-KEY
    ○ HEAP-MAXIMUM

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值