堆
1.定义
堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。
堆满足以下性质:
①堆中某个节点的值总是不大于或不小于其父节点的值。
②堆总是一棵完全二叉树。
(完全二叉树:若二叉树的深度为h,则除第h层外,其他层的结点全部达到最大值,且第h层的所有结点都集中在左子树。)
2.类型
①大根堆:任何一个子树的最大值都在这个子树的根结点。
②小根堆:任何一个子树的最小值都在这个子树的根结点。
3.应用
①堆排序(时间复杂度:n∗logn)
②寻找最值
4.基本操作
以小顶堆实现几种操作(h为堆,size为节点数量)
堆的向下调整
void down(int u)
{
int t=u;//用t表示父节点
if(2*u<=size&&h[u*2]<h[t]) t=u*2;
//存在左儿子且左儿子比父节点小 更新父节点
if(2*u+1<=size&&h[u*2+1]<h[t]) t=u*2+1;
//存在右儿子且右儿子比父节点小 更新父节点
if(t!=u){
swap(h[u],h[t]);//交换
down(t); //递归到下一层
}
}
堆的向上调整
void up(int u)
{
int t=u;//用t表示当前点
while(u/2&&h[t]<h[u/2]){
//存在父节点且父节点比当前点大
swap(h[t],h[u/2]);
u/=2;
}
}
建堆
//两种方式
//将数直接存入h数组,然后从倒数第二层下up一遍,时间复杂度 O(n);
void build_heap()
{
for(int i=n/2;i;i--)
down(i);
}
//或直接每次 insert(x) 时间复杂度 O(n*logn)
插入操作
void insert(int x)
{
h[++size]=x; //将插入数放到堆底
up(size); //进行up操作调整位置
}
删除堆顶元素
void del_top()
{
h[1]=h[size]; //将堆顶数覆盖
size--; //节点个数减1
down(1); //进行down操作调整位置
}
删除任意元素
void del(int k)
{
h[k]=h[size]; //将位置为k的数覆盖
size--; //删除元素树的大小减一
down(k);
up(k); //调整
}
修改任意元素
void modify(int k,int x)
{
h[k]=x; //将位置为k的数修改为x
down(k);
up(k); //调整
}
1
/ \
2 3
/ \ / \
3 4 5 6
/ \
7 8