优先队列-堆

这篇博客展示了如何使用Java实现一个基于数组的小型优先队列,包括offer、poll和peek等基本操作。作者通过shiftUp和shiftDown方法确保了堆的性质,并提供了检查堆正确性的功能。在测试部分,队列被填充并进行了各种操作,验证了其正确性和功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. package cn.tan.heap;
  2. import java.lang.reflect.Array;
  3. import java.util.Arrays;
  4. //优先队列默认小堆
  5. public class MyPriorityQueue {
  6. private long[] arr;
  7. private int size;
  8. public int size(){
  9. return size;
  10. }
  11. public boolean isEmpty(){
  12. return size==0;
  13. }
  14. public MyPriorityQueue(){
  15. arr=new long[16];
  16. size=0;
  17. }
  18. //offer用向上调整,因为插入用的是尾插,所以需要对新插入的元素进行调整
  19. public void offer(long e){
  20. ensureCapacity();
  21. arr[size]=e;
  22. size++;
  23. shiftup(arr,size-1);
  24. }
  25. // 前提:size > 0
  26. public long peek() {
  27. // 返回堆顶元素
  28. if (size < 0) {
  29. throw new RuntimeException("队列是空的");
  30. }
  31. return arr[0];
  32. }
  33. //删除并返回堆顶元素
  34. public long poll(){
  35. if(size<0){
  36. throw new RuntimeException("队列是空的");
  37. }
  38. long e=arr[0];
  39. arr[0]=arr[size-1];
  40. arr[size-1]=0;
  41. size--;
  42. shiftDown(arr,size,0);
  43. return e;
  44. }
  45. private void shiftDown(long[] arr, int size, int index) {
  46. while (2*index+1<size){
  47. int min=index*2+1;
  48. int right=min+1;
  49. if(right<size&&arr[right]<arr[min]){
  50. min=right;
  51. }
  52. if(arr[index]<=arr[min]){
  53. return;
  54. }
  55. swap(arr,min,index);
  56. index=min;
  57. }
  58. }
  59. private void shiftup(long[] arr, int index) {
  60. while(index!=0){
  61. int parent=(index-1)/2;
  62. if(arr[parent]<=arr[index]){
  63. return;
  64. }
  65. swap(arr,parent,index);
  66. index=parent;
  67. }
  68. }
  69. public void check(){
  70. if(size<0||size>arr.length){
  71. throw new RuntimeException("size 约束错误");
  72. }
  73. for(int i=0;i<size;i++){
  74. int left=2*i+1;
  75. int right=left+1;
  76. if(left>=size){
  77. continue;
  78. }
  79. if(arr[i]>arr[left]){
  80. throw new RuntimeException(String.format("[%d]位置的值大于其左孩子的值了",i));
  81. }
  82. if(right<size&&arr[i]>arr[right]){
  83. throw new RuntimeException(String.format("[%d]位置的值大于其右孩子的值了",i));
  84. }
  85. }
  86. }
  87. private void swap(long[] array, int i, int j) {
  88. long t= array[i];
  89. array[i] = array[j];
  90. array[j] = t;
  91. }
  92. private void ensureCapacity() {
  93. if(size<arr.length){
  94. return;
  95. }
  96. arr= Arrays.copyOf(arr,arr.length*2);
  97. }
  98. }
  1. 很重要的属性:堆 = 数组 + 有效元素个数

  2. 优先队列三个重要操作,offer(),poll(),peek();

    1. package cn.tan.heap;
    2. public class Test {
    3. public static void main(String[] args) {
    4. MyPriorityQueue pq=new MyPriorityQueue();
    5. pq.check();
    6. pq.offer(3);
    7. pq.check();
    8. pq.offer(7);
    9. pq.check();
    10. pq.offer(1);
    11. pq.check();
    12. pq.offer(2);
    13. pq.check();
    14. pq.offer(5);
    15. pq.check();
    16. pq.offer(0);
    17. long peek=pq.peek();
    18. System.out.println(peek);
    19. System.out.println("=======");
    20. while(!pq.isEmpty()){
    21. long poll=pq.poll();
    22. pq.check();
    23. System.out.println(poll);
    24. }
    25. }
    26. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他
点击体验
DeepSeekR1满血版
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回顶部