• 数据结构(9)树形结构——大顶堆、小顶堆


    目录

    9.1.概述

     9.2.操作

    9.2.1.插入

    9.2.2.删除

    9.2.3.代码实现


    9.1.概述

    概念:

    根节点是自己所在子树中的最值完全二叉树。

    根节点是所在子树的最大值,称为大顶堆

    根节点是所在子树的最小值,称为小顶堆

    堆的任何子树的根节点到子树上的任意节点,路径上的节点都是有序的,大顶堆为降序,小顶堆为升序。

    此处展示一个大顶堆:

    作用:

    堆一般用来在大量数据中找到前N大或者前N小的数据。

    存储:

    一般用数组来存储堆,首先因为堆一般是从空树开始建立的,不论如何操作其一定会是一颗完全二叉树,不存在大量非叶子结点没有左右孩子的情况,所以用数组来表示不会造成内存浪费。其次堆的删除操作需要从叶节点反向向根结点方向遍历,链表结构不太好支持这种反向遍历。

     9.2.操作

    9.2.1.插入

    堆的插入采用尾插法,新入堆的节点挂在最后一个叶节点上,然后往上浮(交换位置)。

    假设已有一颗树,是按照44、25、31、18、10的插入顺序建树的。

    假设插入的是20:

     假设插入的是35:

    9.2.2.删除

    堆的删除操作,从叶子结点开始删除的话,直接删除即可,不会有任何影响,只有在删除非叶子结点时才要考虑进行结点间的调整,保持堆是大顶堆或者小顶堆。

    堆在使用时每次弹出的都是堆顶的数据,因此删除操作都是针对堆顶元素的,此处以大顶堆的删除操作为例:

    用最末尾的叶节点替换根节点,然后新的根节点与左右孩子比较是否为最大值,若不为最大值,则与参与比较的三个节点中的最大值互换位置,然后递归以上过程,出口为到达叶节点或者到达合适位置。

    9.2.3.代码实现

    1. package linearStructure.tree.heap;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. public class MaxTopHeap {
    5. //存储堆的数组
    6. private int[] heap;
    7. //堆的最大存储容量
    8. private int maxSize;
    9. //当前堆的存储数量
    10. private int heapSize;
    11. public MaxTopHeap(int maxSize) {
    12. this.heap = new int[maxSize];
    13. this.maxSize = maxSize;
    14. this.heapSize = 0;
    15. }
    16. // 判断是否为空的方法
    17. public boolean isEmpty() {
    18. return heapSize == 0;
    19. }
    20. // 判断是否填满
    21. public boolean isFull() {
    22. return heapSize == maxSize;
    23. }
    24. // 获取堆顶的值
    25. public int peek() throws Exception {
    26. if (heapSize == 0) {
    27. throw new Exception("heap is empty");
    28. }
    29. return heap[0];
    30. }
    31. // 往堆中添加值
    32. public void insert (int value) throws Exception {
    33. if (heapSize == maxSize) {
    34. throw new Exception("head is full");
    35. }
    36. heap[heapSize] = value;
    37. heapSize++;
    38. buildMaxHeap(heap);
    39. }
    40. // 删除堆顶值
    41. public int poll() throws Exception {
    42. if (heapSize == 0) {
    43. throw new Exception("heap is empty");
    44. }
    45. int ans = heap[0];
    46. swap(heap,0,--heapSize);
    47. buildMaxHeap(heap);
    48. return ans;
    49. }
    50. // 建大顶堆
    51. private int[] buildMaxHeap(int[] array) {
    52. for (int i = (heapSize-2)/2; i >= 0; i--) {
    53. adjustDownToUp(array,i,heapSize);
    54. }
    55. return array;
    56. }
    57. private void adjustDownToUp(int[] array, int index, int length) {
    58. int temp = array[index];
    59. for (int i = 2*index+1; i < length; i = 2*i+1) {
    60. if (i < length-1 && array[i] < array[i+1]) {
    61. i++;
    62. }
    63. if (temp >= array[i]) {
    64. break;
    65. } else {
    66. array[index] = array[i];
    67. index = i;
    68. }
    69. }
    70. array[index] = temp;
    71. }
    72. // 交换元素值
    73. private void swap(int[] arr, int i, int j) {
    74. int temp = arr[i];
    75. arr[i] = arr[j];
    76. arr[j] = temp;
    77. }
    78. // 获取所有元素
    79. public List getAllElements() {
    80. List ans = new ArrayList<>();
    81. for (int i = 0; i < heapSize; i++) {
    82. ans.add(heap[i]);
    83. }
    84. return ans;
    85. }
    86. }

  • 相关阅读:
    C语言面试题值反转字符串
    Redis-命令操作Redis
    javaweb没有web.xml设置方法
    面向对象【递归方法】
    【andv】a-select 多条数据重复(搜索无效)的问题:
    JS里arguments的作用
    shouldComponentUpdate 是做什么的?
    自定义控件——视图的构建过程——视图的绘制方法
    2022“杭电杯”中国大学生算法设计超级联赛(第一场) to be continued
    Python总结
  • 原文地址:https://blog.csdn.net/Joker_ZJN/article/details/128163031