目的:处理流式数据,即维护动态变化的序列
常见用法:1、合并多个有序数列。
2、优先级队列 -- 一般需要频繁入队和频繁把优先级最高的元素出队。
底层实现:
堆分为小根堆(根最小)和大根堆
基本方法:void down(int index);void up(int index);
他们的作用是把下标为index的结点向上或向下移动,当已经处于最佳位置时,调用方法不会改变它的位置。
以上两种基础的方法可以组成堆中以下重要的几个操作
4.5.特别说明,删改该元素后会有两种情况,该位置更改过的树需要向下走还是想上走,在这里的处理办法是连续调用down up两个方法,实际上只有一个方法会工作。
代码
const int N = 100010;
int h[N], hp[N], ph[N];
//hp代表这是第几个插入的数
//ph[k]表示第k个插入的数在哪里
int cnt;
//cnt记录堆中元素个数
void heap_swap(int a,int b)
{
swap(ph[hp[a]], ph[hp[b]]);
swap(hp[a], hp[b]);
swap(h[a], h[b]);
}
void down(int u)
{
int t = u;//t存储最小值
if (u * 2 <= cnt && h[u * 2] < h[t]) t = 2 * u;
if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = 2 * u + 1;
if (u != t)
{
heap_swap(u, t);
down(t);
}
}
void up(int u)
{
while (u / 2 && h[u / 2] > h[u])
{
heap_swap(u / 2, u);
u /= 2;
}
}