我们今天学了二叉堆,虽然早上拍毕业照没上到课,下午恶补了下还可以接受。

正题:

我们学的好像是二叉堆,感觉和完全二叉树类似.

我认为完全二叉树应该是深度为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

原文地址:https://www.cnblogs.com/ZY2510998968/p/9108629.html