1 package com.rao.linkList; 2 3 /** 4 * @author Srao 5 * @className BinaryHeap 6 * @date 2019/12/3 14:14 7 * @package com.rao.linkList 8 * @Description 二叉堆 9 */ 10 public class BinaryHeap { 11 12 /** 13 * 在插入一个节点之后,数组进行上浮 14 * @param arr:左孩子等于n*2+1,右孩子等于n*2+2 15 * @param length:表示数组的长度 16 */ 17 public int[] upAdjust(int[] arr, int length){ 18 //代表新插入的节点的下标 19 int child = length - 1; 20 21 //求出父节点的下标 22 int parent = (child-1)/2; 23 24 //获得插入的节点 25 int temp = arr[child]; 26 27 //与父节点进行比较,如果父节点大于子节点,就把父节点赋值给子节点,然后把子节点指向父节点 28 while (child > 0 && arr[parent] > temp){ 29 arr[child] = arr[parent]; 30 child = parent; 31 //无论时左孩子还是右孩子,求父节点都是用这个公式 32 parent = (child-1)/2; 33 } 34 35 //如果父节点比子节点要小,此时arr[parent] < temp 36 arr[child] = temp; 37 return arr; 38 } 39 40 /** 41 * 在二叉堆当中,一般是删除根元素,在删除根元素之后,把最后一个元素当作根元素,然后进行下沉 42 * @param arr 43 * @param parent:被当作根元素的节点,从这个元素开始下沉 44 * @param length:数组的长度 45 * @return 46 */ 47 public int[] downAdjust(int[] arr, int parent, int length){ 48 //获取临时的根节点 49 int temp = arr[parent]; 50 51 //计算左孩子节点 52 int child = parent*2+1; 53 54 //进行下沉操作 55 while (child < length){ 56 //先对比左右孩子的大小,用小的那一个进行操作 57 if (child+1 < length && arr[child+1] < arr[child]){ 58 child++; 59 } 60 //如果父节点比子节点小,就直接退出 61 if (temp <= arr[child]){ 62 break; 63 }else {//如果父节点比子节点大,就把子节点赋值给父节点 64 arr[parent] = arr[child]; 65 //让父节点指针指向子节点 66 parent = child; 67 child = parent*2+1; 68 } 69 } 70 arr[parent] = temp; 71 return arr; 72 } 73 74 /** 75 * 根据数组构建一个二叉堆 76 * @param arr:数组 77 * @param length:数组长度 78 * @return 不能从二叉堆的第一个元素开始下沉,要用二叉堆的最后一个非叶子节点开始下沉 79 * 如果从二叉堆的根节点开始下沉,那么可能最上面的三个元素时二叉堆,但是下面的元素还是乱的 80 */ 81 public int[] bulidHeap(int[] arr, int length){ 82 for (int i = (length-1)/2; i>=0; i--){ 83 downAdjust(arr, i, length); 84 } 85 return arr; 86 } 87 88 }
https://www.cnblogs.com/skywang12345/p/3610187.html
上面的博客中有比较好的图,可以参考一下,按着那个图我用Java实现了一下,注释也写的比较全面
原文地址:https://www.cnblogs.com/rao11/p/11976960.html
时间: 2024-08-10 21:14:27