优先队列:特殊的队列,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序

    堆的两个特性
    结构性:用数组表示的完全二叉树
    有序性:任一结点的关键字是其子树所有结点的最大值/最小值

    1. public class MaxHeap{
    2. private int size; //当前元素个数
    3. private int capacity; //容量
    4. private int[] item;
    5. MaxHeap(int capacity){
    6. size = 0;
    7. this.capacity = capacity;
    8. item = new int[capacity + 1];
    9. item[0] = Integer.MAX_VALUE; //哨兵
    10. }
    11. public void insert(int val){
    12. if(isFull())
    13. System.out.println("插入时最大堆已满");
    14. else{
    15. int i = size + 1; //指向末尾空的地方
    16. while(val > item[i / 2]){
    17. item[i] = item[i / 2]; //把父节点换下来
    18. i = i / 2;
    19. }
    20. item[i] = val;
    21. size ++;
    22. }
    23. }
    24. public int delete(){
    25. if(isEmpty()){
    26. System.out.println("删除时最大堆为空");
    27. return -1;
    28. }
    29. else{
    30. int result = item[1]; //把最大值保存起来
    31. int temp = item[size]; //取最后一个节点
    32. size--;
    33. int parent, child;
    34. for(parent = 1; parent * 2 <= size; parent = child){
    35. child = parent * 2; //左儿子下标
    36. //右儿子存在且右儿子较大
    37. if(child != item.length && item[child] < item[child + 1]){
    38. child++; //指向右儿子
    39. }
    40. //此时child指向左右儿子中较大者
    41. if(temp > item[child])
    42. break;
    43. else //把大的换上来
    44. item[parent] = item[child];
    45. }
    46. item[parent] = temp;
    47. return result;
    48. }
    49. }
    50. public boolean isFull(){
    51. return size == capacity;
    52. }
    53. public boolean isEmpty(){
    54. return size == 0;
    55. }
    56. public static void main(String[] args) {
    57. MaxHeap maxHeap = new MaxHeap(5);
    58. maxHeap.insert(6);
    59. maxHeap.insert(3);
    60. maxHeap.insert(2);
    61. maxHeap.insert(4);
    62. maxHeap.insert(5);
    63. System.out.println(maxHeap.delete());
    64. System.out.println(maxHeap.delete());
    65. System.out.println(maxHeap.delete());
    66. System.out.println(maxHeap.delete());
    67. System.out.println(maxHeap.delete());
    68. }
    69. }

    因为堆是完全二叉树,一定是平衡的,插入、删除时间复杂度与树的高度有关:堆 - 图1

    建立堆时

    • 通过插入操作,将N个元素一个个相继插入到一个初始为空的堆中去,时间代价为堆 - 图2
    • 将N个元素按输入顺序存入,先满足完全二叉树的结构特性。调整各结点位置,以满足最大堆的有序特性,时间代价为堆 - 图3