我们今天学了二叉堆,虽然早上拍毕业照没上到课,下午恶补了下还可以接受。
正题:
我们学的好像是二叉堆,感觉和完全二叉树类似.
我认为完全二叉树应该是深度为K且从0-(k-1)深度每一层都是满的,也就是2^i个节点,而最后一层必须先有左边再有右边,是有顺序的.
堆有几个重要的操作:
插入:
将这个数先放在最后,在一直上浮,就插入完成了,代码如下:
dp[++cnt]=a;
int c=cnt;
while(c>>1>0)
{
if(dp[c>>1]>dp[c])
{
swap(dp[c>>1],dp[c]);
c>>=1;
}
else break;
}
删除:
先将根节点赋值为最后一个数,在一直下沉,个数减1个;
dp[1]=dp[cnt--];
int c=1,d;
while(c<<1<=cnt)
{
d=c<<1;
if(d+1<=cnt&&dp[d]>dp[d+1])
d++;
if(dp[c]>dp[d])
{
swap(dp[c],dp[d]);
c=d;
}
else break;
}
上面的都是小根堆,如果是大根堆的话符号反下即可;
有一些题是在n个数中找出第m小的
用堆可以快一点
方案(1)
小根堆
先把n个数都放入到堆中,在弹出根节点m-1次之后的根节点就是答案了
方案(2)
大根堆
每次只要堆里面维护m个数,如果不够,直接加,如果满了,判断当前要加进来的值和根节点比较,如果小于的话就更新根节点再下沉,做到最后根节点也是我的答案了
我本来使用第一种的,结果听老师分析了一波,感觉第二种更方便;
5.29 随笔 over