二叉堆及优先级队列

数据结构既包括各数据存储的方式和彼此间的关系结构,又含有“添加”、“取出”等对数据的操作,同时也带有取出和添加数据时的规则。如队列和栈就是以数据抵达的先后顺序来形成这一规则的,但优先级队列则是以数据内的键值作为基准来判断谁先被取出。

二叉搜索树(按照左子节点、父节点、右子节点的顺序将键值由小到大排序)可实现优先级队列,但是较复杂。而二叉堆的数据结构则较容易实现。二叉堆的逻辑结构是完成二叉树,但可用以1为小标的一维数组表示。此外又可分为最大堆和最小堆。

由于二叉堆可用一维数组来表示,且根的小标为1。则设表示二叉堆的数组为A,二叉堆大小为H,那么二叉堆的元素就存储在A[1,...,H]中,当给定一个结点的小标i时,则可得到其父节点(i/2)、左子节点(2*i)、右子节点(2*i+1)。

1、使用给定数组生成最大堆的实现

// maxHeapify(A, i) 使以i为根结点的子树成为最大堆看,设堆大小为H

maxHeapify(A, i)
    l = left(i) // 左子结点
    r = right(i) // 右子结点
    // 从左子结点、自身、右子节点中选出最大的结点
    largest = max{A[l], A[i], A[r]}的小标
    
    if largest != i     //i的子节点更大
        交换A[i] 与A[largest]
        maxHeapify(A, largest) //递归调用

  

// 通过自底向上地套用maxHeapify的方式,将数组A转为最大堆

buildMaxheap(A)
    for i = H/2 downto 1
        maxHeapify(A, i)

  

优先级队列中各个元素都包含键值,其存储在数据集合S中,

insert(S, k):向集合S中插入元素k

extractMax(S): 从S中删除键值最大的元素并返回键值

2、向优先级队列中插入元素

// 更改优先级队列中元素的键值
heapIncreaseKey(A, i, key)
    if key < A[i]
        error: 新键值小于当前键值
    A[i] = key
    while i >1 && A[parent(i)] < A[i]
        交换A[i] 和A[parent(i)]
        i = parent(i)

  

insert(key)
    H++
    A[H] = -INFTY
    heapIncreaseKey(A, H, key) //在A[H]中设置key值

  

3、获取、删除堆中最大元素

heapExtractMax(A)
    if H < 1
        error:
    max = A[1]
    A[1] = A[H]
    H--
    maxHeapify(A, 1)
    return max

  

posted @ 2017-10-14 22:14  zmlgo  阅读(384)  评论(0编辑  收藏  举报