堆结构:
(1)逻辑概念上:完全二叉树(满二叉树或者是从左往右依次变满的二叉树)
(2)存储表示:数组从0出发的连续一段表示一颗完全二叉树,使用size描述该树有多少结点,在i位置上的结点,其左孩子下标为(2*i+1),右孩子下标为(2*i+2),父节点为(i-1)/2.
(3)分类:
大根堆:堆顶为整个堆最大的元素,同样的每个子树也满足子树的最大值是头结点的值
小根堆:堆顶为整个堆最小的元素,同样的每个子树也满足子树的最小值是头结点的值
两个重要过程:
heapinsert:向上跟父节点比较调整的过程
/*
从堆底向上升的过程
某个数在arr的index位置,通过该方法找到它应该在的大根堆的位置
方法:依次向上找父节点,直到父节点比该数大
*/
public static void heapinsert(int[] arr, int index){
while(arr[index] > arr[(index - 1)/2]){//包含index在0位置的情况
swap(arr, index, (index-1)/2);
index = (index - 1) / 2;
}
}
heapify:向下跟子节点比较调整的过程
/*
某个数在index位置,是否能往下沉找到应该在的位置
大根堆方法:与左右孩子的最大值交换,在依次和下面的孩子比较
*/
public static void heapify(int[] arr, int index, int heapSize){
int left = index * 2 + 1; //左孩子的下标
while(left < heapSize){ //如果有孩子
//如果有右孩子,找出左右孩子中的较大的下标
int largest = left + 1 < heapSi