堆的用法解析

it2026-02-04  1

基本介绍: 堆是一个基于树的特殊数据结构,支持插入、删除、查询最值。它满足每一个子树的根节点一定保存着这棵子树中的最值。大根堆保存的就是最大值,小根堆保存的就是最小值。这里我们只介绍基本的二叉堆的用法。 关于二叉堆: 二叉堆就是一棵满足“堆性质”的完全二叉树。我们在这里使用数组来存储堆,左子节点的下标就是父节点下标乘以2,右子节点的下标就是父节点下标乘以2+1.这样的方法可以推广到k叉堆,这里就不细说了。 基本操作:

定义:int heap[maxn],count1 count1中保存的是根中的节点数根据完全二叉树的性质,所以count1同时也是最后一个结点的下标插入: 插入的时候,我们直接将要插入的节点放在最后,由void insert(node temp)实现。然后我们从这个节点开始向上维护堆,由void up(ll son)实现,让这个节点去到该去的地方,根据大小根堆的不同,调整判断交换的条件。 void up(ll son) { while(son>1) { if(heap[son].val<heap[son/2].val) { swap(heap[son],heap[son/2]); son>>=1; } else break; } } void insert(node temp) { heap[++count1]=temp; up(count1); } 获得堆顶的值: ll GetTop() { return heap[1]; } 删除 删除的时候,我们直接将要删除的节点和最后的节点交换,并将count1减1,表示最后一个节点被舍弃,由void Remove()实现。然后我们从原来的那个节点的位置开始向上向下维护堆,由void up(ll son)和void down(ll fa)实现。 void down(ll fa) { ll son=fa*2; while(son<=count1) { if(son<count1 && heap[son].val>heap[son+1].val) son++; if(heap[son].val<heap[fa].val) { swap(heap[son],heap[fa]); fa=son; son=fa*2; } else break; } } void Remove(ll p) { heap[p]=heap[count1--]; up(p);down(p); }

推荐习题: POJ1456 Supermarket,POJ2442 Sequence,洛谷P3620 数据备份,洛谷P1091 合并果子

最新回复(0)