堆是什么?
这里的堆不是用于保存动态分配对象的堆(与栈对应),即不是内存中的一块区域,而是一种数据结构。
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式 存储 在一个一维数组中,并满足:
则 称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
堆在逻辑概念上是一颗完全二叉树,父子结点之间有顺序;物理概念上是一个一维的有序数组
如果i为0,则i表示的节点为根节点,否则i节点的双亲节点为 (i - 1)/2
如果2 * i + 1 小于节点个数,则节点i的左孩子下标为2 * i + 1,否则没有左孩子
如果2 * i + 2 小于节点个数,则节点i的右孩子下标为2 * i + 2,否则没有右孩子
堆的创建
将一个普通无序数组变成变成堆的过程称为heapify,基本思路就是从最后一个非叶子节点开始,一直往前直到根,对每个节点,执行***向下调整***(最小堆)。
完全二叉树中最后一个非叶子结点:size/2
或者(n-1)/2
这是最后一个结点的父结点
这是一个建立小堆的过程:
堆向下调整是建堆过程中的核心操作,当完全二叉树的左右子树都已经是堆时,可以直接shifDown建堆
//在调整以parent为根的二叉树时,必须要满足parent的左子树和右子树已经是堆了才可以向下调整。
//建一个大堆
public static void shiftDown(int []arr,int index){
int parent = index;//parent是从最后一个非叶子节点开始,index变量使得代码看起来更加直观
int child = 2 * parent + 1;
int size = arr.length;
while(child < size)