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