基于堆的排序(HEAP_SORT)和优先队列(priority queue)

堆排序

维护最大堆伪代码:

//递归调用
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 != i
        exchange A[i] with A[largest]
        MAX_HEAPIFY(A, largest)
//循环调用
MAX_HEAPIFY(A, i)
    while true
        l = 2i
        r = 2i+1
        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 != i
            exchange A[i] with A[largest]
            i = largest
        else break

建堆:

//O(n) 线性时间内把无序数组构造成为一个最大堆
BUILD_MAX_HEAP(A)
    A.heap_size = A.length
    for i = A.length/2 downto 1    //自底向上
        MAX_HEAPIFY(A, i)

排序:

由于最大堆中的最大数永远是A[1],所以每次将A[1]与A[n]交换,之后不考虑A[n]。调用 MAX_HEAPIFY(A, 1),直至 A.length到2


HEAPSORT(A)
    BUILD_HEAP(A)
    for i = A.length downto 2
        exchange A[1] with A[i]
        A.heap_size = A.heap_size - 1    //保证调用MAX_HEAPIFY(A, i)时正确
        MAX_HEAPIFY(A, 1)

优先队列(Priority queue)

HEAP_MAXIMUM(A)获取队顶元素:堆顶A[1]永远是最大的

HEAP_MAXIMUM(A)
    return A[1]

HEAP_EXTRACT_MAX(A)删除并返回​​​​​堆顶元素

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_HEAPIFY(A, 1)
    return max

HEAP_INCREASE_KEY(A, i, key) 将下标为 i 的元素改为 key
(此处保证key>=A[i], 若key<A[i] 可以再次调用MAX_HEAPIFY(A, i)来维护堆)

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]     //父亲节点值小于key
        exchange A[i] with A[PARENT(i)]
        i = PARENT(i)

MAX_HEAP_INSERT(A, key) 将key插入堆中

MAX_HEAP_INSERT(A, key)
    A.heap_size = A.heap_size + 1
    A[A.heap_size] = -inf
    HEAP_INSCREASE_KEY(A, A.heap_size, key)

同理使用最小堆可以实现最小优先队列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值