堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。
大根堆和小根堆介绍:
- 大根堆:任意一颗子树,其最大值在树根处的堆结构
- 小根堆:任意一颗子树,其最小值在树根处的堆结构
堆结构根节点和叶子节点坐标索引关系
- 任意i位置的节点其左子节点的坐标索引为:2*i+1
- 任意i位置的节点其右子节点的坐标索引为:2*i+2
- 任意i位置的节点其父节点的索引坐标为 :(i-1)/2 (向下取整)
对于一个堆结构,需要实现两个基本的方法用来维护堆的特点,一个向上调整,即将其调整到所有小于它的父节点上面去(上浮);一个向下调整,将所有大于它的子节点向上调(下沉),具体见代码实现:
import cn.algorithms.util.ArrayUtil;
/**
* Created with IntelliJ IDEA.
*
* @Description:
* @Auther: TaoistQu
* @Date: 2021/05/16/17:25
*/
public class HeapUtil {
/**
* @param arr
* @param index 给定的要插入的索引位置
*/
public static void heapInsert(int[] arr, int index) {
while (arr[index] > arr[((index - 1) / 2)]) {
ArrayUtil.swap(arr, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
/**
* @param arr 堆数组
* @param index 要开始modify的位置
* @param heapSize 堆的大小
*/
public static void heapify(int[] arr, int index, int heapSize) {
int left = index * 2 + 1;
while (left < heapSize) {
int largest = (left + 1) < heapSize && arr[left + 1] > arr[left] ? (left + 1) : left;
largest = arr[largest] > arr[index] ? largest : index;
if (largest == index) {
break;
}
ArrayUtil.swap(arr, largest, index);
index = largest;
left = index * 2 + 1;
}
}
}
利用这两个核心方法实现一个自己的堆:
package cn.dataStructures.heap;
import cn.algorithms.util.ArrayUtil;
import cn.dataStructures.heap.util.HeapUtil;
/**
* Created with IntelliJ IDEA.
*
* @Description: 大根堆 即为完全二叉树 任意一颗子树的最大值在树根上
* <p>
* i位置的节点的
* 左子节点索引为:2*i+1
* 右子节点索引坐标为:2*i+2
* 父节点坐标为: (i-1)/2
* </p>
* @Auther: TaoistQu
* @Date: 2021/05/15/19:18
*/
public class Heap {
private int[] heap;
private final int limit;
private int heapSize;
public Heap(int limit) {
heap = new int[limit];
this.limit = limit;
heapSize = 0;
}
public boolean isEmpty() {
return heapSize == 0;
}
public boolean isFull() {
return heapSize == limit;
}
public void push(int value) {
if (heapSize == limit) {
throw new RuntimeException("heap is full");
}
heap[heapSize] = value;
HeapUtil.heapInsert(heap, heapSize++);
}
public int pop() {
int ans = heap[0];
ArrayUtil.swap(heap, 0, --heapSize);
HeapUtil.heapify(heap, 0, heapSize);
return ans;
}
}