优先队列PriorityQueue类

提前告知:

        涉及到最小堆,请看我的另一篇blog:【数据结构】堆 以及 堆排序_向前走-CSDN博客


 

简单描述

        PriorityQueue和Queue的区别在于,它的出队顺序与元素的优先级有关,对PriorityQueue调用remove()或poll()方法,返回的总是优先级最高的元素。

        要使用PriorityQueue,我们就必须给每个元素定义“优先级”。

                结论:可以通过重写PriorityQueue类中的Comparetor实现控制元素优先级。

通过源码理解

    成员变量

构造器:如果给定了定制排序类Comparator,则使用该类确定元素的优先级,否则使用自然排序类Comparable类确定元素的优先级。

成员方法

        提前告知:主要是,添加元素  和  移除元素。因为底层使用的是最小堆来进行优先队列(底层使用数组实现)中元素的优先级控制,所以添加元素使用的是上浮来调整优先级,移除元素使用的是下沉操作来调整优先级。

        添加

 

 上浮的具体实现

移除

综上:

        因为重写Comparator接口实现类中的compare(Object o1, Object o2)方法,如果返回值大于0,表示o1大于o2,如果返回值等于0,表示o1等于o2,如果o1小于o2,表示o1小于o2。

        不使用Comparator接口实现类,默认使用Conparable接口实现类中的compareTo方法,o1.compareTo(o2),如果返回值大于0,表示o1大于o2,如果返回值等于0,表示o1等于o2,如果o1小于o2,表示o1小于o2。

        但是PriorityQueue类中根据最小堆进行排序,所以o1和o2中值小的,优先级越高。

使用实例

来源:合并K个排序链表

使用优先队列合并:

    因为有K个链表,而K个链表中每个当前结点都是最小结点,所有通过优先队列存K个结点中的最小值。

代码实现:

使用Comparable接口:

class Solution {
     private PriorityQueue<Status> queue = new  PriorityQueue<Status>();
     
     class Status implements Comparable<Status>{//创造一个容器实现Comparator接口, 并且按照从小到大的顺序装载数据
          private int val;
          private ListNode ptr;
          
          public Status(int val, ListNode ptr) {
              this.val = val;
              this.ptr = ptr;
          }
          
          @Override
          public int compareTo(Status o2) {
              return this.val - o2.val;
          }
     }
     
    public ListNode mergeKLists(ListNode[] lists) {
     ListNode head = new ListNode();
     ListNode temp = head;
     
     for(ListNode node : lists) {
          if(node != null) {
               queue.offer(new Status(node.val, node));
          }
     }
     
     while(!queue.isEmpty()) {
          Status poll = queue.poll();//出队的是某个链表的当前最小值
          temp.next = poll.ptr;
          temp = temp.next;
          if(poll.ptr.next != null) {
               queue.offer(new Status(poll.ptr.next.val,  poll.ptr.next));
          }
     }
     
     return head.next;
    }
}

使用Comparator接口:

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
     PriorityQueue<ListNode> queue = new  PriorityQueue<ListNode>(new Comparator<ListNode>() {
              @Override
              public int compare(ListNode o1, ListNode  o2) {
                   return o1.val - o2.val;
              }
          });
     
     for(ListNode node : lists) {
          if(node != null) {
               queue.offer(node);
          }
     }
     
     ListNode head = new ListNode();
     ListNode temp = head;
     
     while(!queue.isEmpty()) {
          ListNode minNode = queue.poll();//出队的是某个链表的当前最小值
          temp.next = minNode;
          temp = temp.next;
          if(minNode.next != null) {
               queue.offer(minNode.next);
          }
     }
     
     return head.next;
    }
}

 其中建造最小堆实现的优先队列时,可以使用lambda表达式:

PriorityQueue<ListNode> queue = new  PriorityQueue<ListNode>((o1, o2) -> o1.val - o2.val);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值