算阶2的例题
0x11 栈
0x12 队列
0x13 链表与领接表
0x14 Hash
0x15 字符串
0x16 Trie
0x17 二叉堆
二叉堆
二叉堆含义
支持插入,删除,查询最值,满足堆性质的完全二叉树,树上每个节点有权值,树上任意一个节点的权值都小于其父节点的权值,则称该二叉树满足“大根堆性质”,满足“大根堆性质”的二叉树就是大根堆,这里主要以大根堆为例,小根堆同理可得。
存储方式
层次序列存储方式
编号方法:逐层从左到右编号,作为下标,【父】=【子】
/
2
/2
/2, 【左】=【父】
∗
2
*2
∗2,【右】=【子】
∗
2
+
1
*2+1
∗2+1.
插入Insert
将新节点P直接放在二叉堆末尾,然后通过交换的方式向上
U
P
UP
UP(若P大于父亲,则交换P与它的父亲,再与它新的父亲比较)。
void up(int p){
while(p > 1){//如果不是堆顶
if(heap[p] > heap[p/2]){//与父亲比较大小
swap(heap[p], heap[p/2]);//如果比父亲大,就交换
p /= 2;
}
else break;
}
}
void Insert(int val){
heap[++n] = val;//加到二叉树末尾
up(n);
}
查询最值Gettop
直接访问堆顶
删除堆顶Extract
将堆顶与二叉树末尾互换,移除二叉树末尾,然后向下进行
D
O
W
N
DOWN
DOWN,跟
U
P
UP
UP差不多
void down(int p){
int s = p*2;//左儿子
while(s <= n){
if(s<n && heap[s] < heap[s+1]) s++;//比较左右儿子的大小
if(heap[s] > heap[p]){//如果比儿子小,就互换
swap(heap[p], heap[s]);
p = s; s = p*2;
}
else break;
}
}
void Extract(){
heap[1] = heap[n--];//交换,删除
down(1);
}
删除Remove
删除编号为k的点,与
E
x
t
r
a
c
t
Extract
Extract同理,交换k与二叉树最后一个点,但是要各做一遍
U
P
UP
UP以及
D
O
W
N
DOWN
DOWN。
void Remove(int k){
heap[k] = heap[n--];
up(k); down(k);
}