定义
我们知道,队列的特点是“先进先出“,但如果队列中的某些元素需要先出即“插队”的话,队列无法满足这种要求,于是提出了堆的概念。
堆也称为“优先队列”,是一种特殊的队列,从堆中取出元素是依照元素的优先级大小,而不是进入队列的先后顺序。
操作的时间复杂度
1.普通数组
插入的时间复杂度为O(1),删除元素不仅要遍历,还涉及到其他元素的移动,时间复杂度为O(n)
2.有序数组
可令元素按优先级从低到高排列,这样删除时只要删除最后一个元素即可,时间复杂度为O(1),但是因为需要保持有序,所以插入时需要用O(log n)的时间找到合适的插入位置,并且也涉及到其他元素的移动,最坏情况下时间复杂度仍为O(n)
3.普通链表
插入的时间复杂度为O(1),删除的时间复杂度为O(n)
4.有序链表
插入的时间复杂度为O(n),删除的时间复杂度为O(1)
性质
堆的常用结构时用二叉树表示,不特指的话为一棵完全二叉树,通常不必用指针,而是用数组来实现堆的存储
堆所用数组起始单元为1,在数组中按照完全二叉树的层序存储,根节点放在下标为1的位置中
对于下标为i的结点,其父结点的下标为i/2取整,反过来,i的左右结点分别是2i和2i+1
最大堆和最小堆
最大堆中,任一结点的值大于或等于其子结点的值,根结点元素的值为整个堆中最大的
最小堆中,任一结点的值小于或等于其子结点的值,根结点元素的值为整个堆中最小的
堆结构
typedef struct HNode * Heap; //堆的类型定义
struct HNode{
ElementType *Data; //存储元素的数组
int Size; //堆中当前元素的个数
int Capacity; //堆的最大容量
};
typedef Heap MaxHeap; //最大堆
typedef Heap MinHeap; //最小堆