堆
要了解堆之前,请先了解树,因为堆是一颗完全二叉树
如果不知道的话请点击下方链接了解
要注意的是
-
首先堆是一颗完全二叉树
-
其次堆中存储的值是偏序
Min-heap(小根堆): 父节点的值小于或等于子节点的值
Max-heap(大根堆): 父节点的值大于或等于子节点的值
好吧其实就是实现自动排序
O(logn)时间复杂度内实现插入,删除,O(1)查询
1.堆的数组实现
如果用数组来存储,那么儿子的编号便满足如下的性质
-
左儿子的编号是自己的编号的
x2+1
-
右儿子的编号是自己的编号的
x2+2
代码如下:
int heap[N],sz=0;
void push(int x)
{
int i=sz++;
while(i>0)//往上走
{
//父结点的编号
int p=(i-1)/2;
//如果不需要再交换就break;
if(heap[p]<=x)break;
heap[i]=head[p];
i=p;
}
heap[i]=x;
}
//删除最小值:先把最小值丢掉,先把最后一个节点的值放到根节点处,然后排序交换即可
int pop()
{
//最小值
int ret=heap[0];
int x=heap[--sz];
int i=0;
while(i*2+1<sz)//因为堆是完全二叉树偏左嘛
{
//左右儿子
int a=i*2+1,b=i*2+2;
//选出儿子中最小的
if(b<sz&&heap[b]<heap[a])a=b;
//如果不需要交换就break
if(heap[a]>=x)break;
//交换
heap[i]=heap[a];
i=a;
}
heap[i]=x;
return ret;//返回被丢掉的那个最小值