【Java】PriorityQueue优先级队列

本文介绍了PriorityQueue在Java中的应用,包括堆的数据结构原理、最大堆和最小堆的概念、使用时的注意点,以及如何通过lambda表达式和Comparator实现最大/小堆操作。实例演示了如何构造最小堆和最大堆并输出结果。

PriorityQueue的底层是堆,堆的底层是数组。

一、什么是堆

堆就是一颗顺序存储的完全二叉树,底层是一个数组

  • 堆逻辑上是一颗完全二叉树。
  • 堆物理上是存储在数组中的。
    画个图就好理解了:
    在这里插入图片描述

二、什么是最大堆、最小堆

  • 最大堆:每个节点都大于等于它的两个子节点,排序最前面的元素一定是所有元素中最大的元素。
  • 最小堆:每个节点都小于等于它的子节点,排序在最前面的元素一定是所有元素中最小的元素。
    如下图所示:
    在这里插入图片描述

三、使用注意点

  1. 必须导入PriorityQueue所在的包。
  2. 队列中放置的元素必须要能够比较大小(只有实现了Comparable和Comparator接口的类才能比较大小),不能插入无法比较大小的对象
  3. 不能插入null对象。
  4. 没有容量限制,可以插入任意多个元素,其内部可以自动扩容。

PS:对于第二点中,如果传入的是链表中的节点对象,是无法直接比较大小,只能用链表对应的值才能比较大小。

//1. 最小堆用lamda表达式写,注意是a.val-b.val,而不是a-b
PriorityQueue<ListNode> pq = new PriorityQueue<>((a,b)->(a.val-b.val));

//2.最大堆用lamda表达式写,注意是b.val-a.val,而不是b-a
PriorityQueue<ListNode> pq = new PriorityQueue<>((a,b)->(b.val-a.val));

四、JAVA中使用优先队列,实现最大/小堆

先记住一句口诀:默认使用最小堆,最大堆后面减前面!!!

先来看最小堆

public class SmallHeap {
	public static void main(String[] args) {
		int[] a = {2,17,4,12,8,21,15,33};
		//1,默认实现的是最小堆,元素按照natural ordering排序(自然排序,例如,数字的从小到大)
		PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
		
		for (int i : a) {
            pq.offer(i);
        }
		
		while(!pq.isEmpty()) {
			System.out.print(pq);
		}
		
        //输出(升序):[2, 8, 4, 17, 12, 21, 15, 33]
	}
}

再来看看最大堆

public class Test {
	public static void main(String[] args) {
		int[] a = {2,17,4,12,8,21,15,33};
        //1.可以直接使用lamda表达式实现最大堆
        PriorityQueue<Integer> pq =new PriorityQueue<>((a, b) -> b - a);
        
		//2,通过比较器排序,实现最大堆
/*		PriorityQueue<Integer> pq = new PriorityQueue<Integer>(new Comparator<Integer>() {
 
			@Override
			public int compare(Integer a, Integer b) {
		    //   以下是对比较器升序、降序的理解.
			//	 (1) 写成return a.compareTo(b) 或者 return a-b表示升序(最小堆)
			//	 (2) 写成return b.compareTo(a) 或者 return b-a表示降序(最大堆)				
				return b.compareTo(a);
			}
			
		}) ;
*/    
		for (int i : a) {
            pq.offer(i);
        }
		
		while(!pq.isEmpty()) {
			System.out.print(pq);
		}
 
        //输出(降序):[33, 21, 17, 12, 8, 4, 15, 2]
	}
}

最后补充一些PriorityQueue类常用的函数:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值