定义
- 是一颗完全二叉树
- 每一个结点都大于等于它的子结点(大顶堆),或者小于等于它的子结点(小顶堆)
图解
堆树.png
堆的插入过程
- 从下往上
- 从上往下
其插入的过程就叫做堆化
从下往上.png
堆的删除过程
删除_1.png
删除_2.png
初始化堆的过程
初始化堆_1.png
初始化堆_2.png
代码实现
public class HeapTree { private int[] arr; public HeapTree() { } public HeapTree(int capacity) { arr = new int[capacity]; } /** * 堆化方法 * * @param start {@code int} 化堆结点 * @param end {@code int} 化堆结束点 */ public void heapIndex(int start, int end) { int parent = start; while (parent * 2 + 1 < end) { int son = parent * 2 + 1; if (son + 1 < end && arr[son + 1] < arr[son]) { son = son + 1; } if (arr[son] < arr[parent]) { int temp = arr[son]; arr[son] = arr[parent]; arr[parent] = temp; } parent = son; } } /** * 排序 */ public void sort() { for (int i = arr.length - 1; i > 0; i--) { int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; heapIndex(0, i); } } /** * 创建堆 * * @param arr {@code int[]} 初始堆 */ public void createHeap(int[] arr) { this.arr = arr; int len = arr.length; for (int i = len / 2 - 1; i >= 0; i--) { heapIndex(i, len); } } /** * top K 问题 * * @param number */ public void topK(int number) { if (number < arr[0]) { return; } arr[0] = number; heapIndex(0, arr.length); } public static void main(String[] args) { int[] arr = {30, 23, 17, 18, 5, 10}; HeapTree heapTree = new HeapTree(); heapTree.createHeap(arr); heapTree.sort(); System.out.println(Arrays.toString(arr)); } }
TOP K 问题
给你1亿个的数字(整数,1~2^32-1),求出前10大的数字,还可动态添加新数字。
public class TopKOfNumber { public static void main(String[] args) { HeapTree heapTree = new HeapTree(10); long startTime = System.currentTimeMillis(); final Random random = new Random(); int[] arr = new int[10]; //初始化堆 for (int i = 0; i < 10; i++) { arr[i] = Math.abs(random.nextInt()); } heapTree.createHeap(arr); for (int i = 0; i < 100000000; i++) { int number = random.nextInt(); heapTree.topK(number); } heapTree.topK(Integer.MAX_VALUE); System.out.println(Arrays.toString(arr)); System.out.println("共花费时间: " + (System.currentTimeMillis() - startTime) + "ms"); } }