码迷,mamicode.com
首页 > 其他好文 > 详细

手写堆

时间:2020-04-29 12:33:48      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:优先   queue   class   建堆   操作   heap   c++   表示   size   

手写堆

算法思想

  • 堆是一颗完全二叉树
  • STL里的堆就是优先队列priority_queue
  • 用一维数组存储
  • 下标一定是从1开始,避免0的左儿子2x还是0的冲突
  • 核心操作:down(x)下移节点 up(x)上移节点
  • 插入一个数 heap[++size] = x; up(size);
  • 求集合当中的最小值 heap[1];
  • 删除最小值 heap[1] = heap[size]; size--; down(1);
  • 删除任意一个元素 heap[k] = heap[size]; size--; down(k); up(k);
  • 修改任意一个元素 heap[k] = x; down(k); up(k);

代码实现

int h[N],siz;
//这两个数组存映射关系  ph[k]=i表示第k个插入的数对应堆中的编号为i  
//hp[i] = k表示堆中编号为i的点是第k个插入的数 k从1开始
//一般用到的堆不需要复杂的交换 不需要存储映射
int ph[N],hp[N];

//节点交换函数 同时要修改映射关系
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)
{
    //t是三个里面最小值的编号
    int t = u;
    if((u * 2) <=siz && h[u*2] < h[t]) t = u *2;
    if((u * 2 + 1) <= siz && h[u * 2 + 1] < h[t]) t = u * 2 + 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;
    }
}
for(int i=1;i<=n;i++) cin>>h[i];
siz = n;
//O(n)建堆
for(int i=n/2;i;i--) down(i);

手写堆

标签:优先   queue   class   建堆   操作   heap   c++   表示   size   

原文地址:https://www.cnblogs.com/codertea/p/12801148.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!