二叉堆及优先级队列
数据结构既包括各数据存储的方式和彼此间的关系结构,又含有“添加”、“取出”等对数据的操作,同时也带有取出和添加数据时的规则。如队列和栈就是以数据抵达的先后顺序来形成这一规则的,但优先级队列则是以数据内的键值作为基准来判断谁先被取出。
二叉搜索树(按照左子节点、父节点、右子节点的顺序将键值由小到大排序)可实现优先级队列,但是较复杂。而二叉堆的数据结构则较容易实现。二叉堆的逻辑结构是完成二叉树,但可用以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