首先,堆是一种完全二叉树,堆可以分为最小堆和最大堆。最小堆的儿子节点一定不小于它的父亲节点(a[parent]<=a[child],即根节点最小),最大堆的儿子节点一定不大于它的父亲节点(a[parent]>=a[child],根节点最大)。一般,堆排序算法使用的是最大堆,优先队列使用的是最小堆。
【数据结构|堆】如果把堆看成一棵树,一个堆中的节点的高度就是该节点到叶子节点最长简单路径上边的数目。从而,堆的高度即为根节点的高度。如果一个堆含有n个元素,则该堆的高度为floor(log2n),2是底数,floor()向下取整。
堆的插入与删除操作与堆的深度成正比,所以,如果一共n个元素,那么每个操作可以在O(logn)的时间内完成
堆可以用数组来存储,若记父亲节点下标为i,则左儿子节点下标:2*i+1 。右儿子节点下标:2*i+2 。
实现(以最小堆为例):
//heap为存储堆的数组,sz为堆的元素个数
int heap[MAX],sz = 0;
void push(int x){ //x为要插入的元素
int i = sz++;
//插到最后,元素个数加一
while(i>0){
int p = (i-1)/2;
//与父节点 比较大小
if(heap[p]<=x)//若没有大小颠倒,则退出
break;
heap[i] = heap[p];
//将父节点的值放下来
i = p;
//子节点标记提上去
}
heap[i] = x;
}int pop(){
int ret = heap[0];
//要删除的元素
int x = heap[--sz];
//准备提最后一个元素,且元素个数减一
int i = 0;
//插入位置
while(i*2+1=x)//如果最小的子节点都比自己大,则退出
break;
heap[i] = heap[LeftChild];
//否则将最小的儿子提上来
i = LeftChild;
}
heap[i] = x;
return ret;
}
推荐阅读
- 笔记|C语言数据结构——二叉树的顺序存储和二叉树的遍历
- C语言学习(bit)|16.C语言进阶——深度剖析数据在内存中的存储
- 数据结构和算法|LeetCode 的正确使用方式
- 先序遍历 中序遍历 后序遍历 层序遍历
- 数据结构|C++技巧(用class类实现链表)
- 数据结构|贪吃蛇代码--c语言版 visual c++6.0打开
- 算法|算法-二分查找
- 数据结构学习指导|数据结构初阶(线性表)
- leetcode题解|leetcode#106. 从中序与后序遍历序列构造二叉树
- java|ObjectOrientedProgramming - 面向对象的编程(多态、抽象类、接口)- Java - 细节狂魔