堆
- 定义
堆(二叉)是一个数组,它可以被看成一个近似的完全二叉树。 - 表示
表示堆的一般是数组A,其中,根节点为A[1],其他的节点表示如下:- 一个节点 i 的父节点:A[i/2]
- 一个节点 i 的左子节点:A[i*2]
- 一个节点 i 的右子节点:A[i*2+1]
- 分类
- 最大堆:所有父节点的值大于或等于它两个子节点的值,根节点是堆中最大值的点
- 最小堆:所有父节点的值小于或等于它两个子节点的值,根节点是堆中最小值的点
二叉树
- 满二叉树
- 深度(h)与节点数(n)的关系:n=2^h-1
- 完全二叉树
- 深度(h)与节点数(n)的关系:h=log2(n+1)
- 值按照顺序一一对应,中间不能有缺漏,因此不可能存在有右节点,没有左节点的情况
- 平衡二叉树(待补充)
满二叉树
完全二叉树
堆的操作
维护堆的性质(HEAPIFY)
这里指维护最大堆或最小堆的性质。以最大堆(MAX-HEAPIFY)为例:
复杂度O(lgn)
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[i]
largest=r
if largest!=i
exchange A[i] with A[largest]
MAX-HEAPIFY(A,largest)
建堆(Build-MAX-HEAP)
将A[1……n]转换为最大堆
复杂度:O(n)
Build-MAX-HEAP(A)
A.heap-size=A.length
for i=[A.length/2] downto 1
MAX-HEAPIFY(A,i)
堆的应用
堆排序算法
复杂度:O(nlgn)
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)
优先队列
是一种用来维护由一组元素构成的集合S的数据结构,其中每一个元素都有一个相关值,成为关键字。
- 分类
- 最大优先队列
- 最小优先队列
- 操作
一个最大优先列支持以下操作:(最小优先队列也有以下操作,操作相反)
INSERT(S,x):将元素x插入集合S
MAXIMUM(S):返回S中最大的关键字
MAXIMUM(A)
return A[1]
EXTRACT-MAX(S):去掉并返回S中具有最大关键字的元素
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) #复杂度O(lgn)
return max
INCREASE-KEY(S,x,k):将元素x的关键字增加到k
复杂度:O(lgn)
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]
exchange A[i] with A[PARENT(i)]
i=PARENT(i)
- INSERT(S,k):插入操作
MAX-HEAP-INSERT(A,key)
A.heap-size= A.heap-size+1
A[A.heap-size]=-∞
HEAP-INCREASE-KEY(A,A.heap-size,key)
课堂作业
题目一
合并K个升序列表(待完成)
题目二
给定一个整数nums和整数K,返回其中出现频率前k高的元素(待完成)