Java PriorityQueue(优先级队列,堆)

PriorityQueue

PriorityQueue是Java中的一个容器类,继承关系如下:
java.lang.Object
java.util.AbstractCollection<E>
java.util.AbstractQueue<E>
java.util.PriorityQueue<E>

按照文档中的描述,PriorityQueue是由堆实现的。
由于需要排序,所以PriorityQueue的构造函数可以接收一个Comparator接口的实例,以此来作为比较两个对象大小的依据。

顺带介绍一下Comparator接口,该接口是用来判断两个数之间大小关系的接口,实现该接口需要重写该接口中的一个
int compare(T a, T b) 方法

该方法返回一个int值
文档中对该方法对返回描述为
a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
即返回结果为负数,零,正数,对应a小于,等于,大于b。

我们先写一个Person类作为放在PriorityQueue中对对象。

public class Person {
	private int age;
	public Person(int age)
	{
		this.age = age;
	}
	public int getAge() {
		return age;
	}
}

接下来是一个测试类

public class Test {

	public static void main(String[] args) {
		Person p1 = new Person(1);
		Person p2 = new Person(2);
		Person p3 = new Person(3);
		Person p4 = new Person(4);
		Person p5 = new Person(5);
		PriorityQueue<Person> pq = new PriorityQueue<>((n1,n2)->n1.getAge()-n2.getAge());
		pq.offer(p3);
		pq.offer(p5);
		pq.offer(p2);
		pq.offer(p1);
		pq.offer(p4);
		Iterator<Person> it = pq.iterator();
		while(it.hasNext())
		{
			Person temp = (Person) it.next();
			System.out.println(temp.getAge());
		}
		while(!pq.isEmpty())
		{
			Person p = (Person)pq.poll();
			System.out.println(p.getAge());
		}	
	}
}

在创建PriorityQueue时使用了lambda语句

PriorityQueue<Person> pq = new PriorityQueue<>((n1,n2)->n1.getAge()-n2.getAge());

然后用offer方法把创建的Person对象放入队列。然后我们用两种方法打印队列元素。

方法一 Iterator

通过迭代器来打印优先级队列重的元素

Iterator<Person> it = pq.iterator();
		while(it.hasNext())
		{
			Person temp = (Person) it.next();
			System.out.println(temp.getAge());
		}

放入队列的顺序为35214,而打印出来的元素为12354
我们发现打印出来的元素并不是按照从小到大的顺序排列的。
因为,PriorityQueue是使用堆实现的,而堆只保证上层的元素大于(或小于)下层的元素,并且堆顶是最大(或最小)的元素。

方法二 取对头对象

while(!pq.isEmpty())
		{
			Person p = (Person)pq.poll();
			System.out.println(p.getAge());
		}	

由于PriorityQueue继承自队列,所以我们可以使用poll()弹出队头对象,也就是堆顶对象,在弹出堆顶对象时,PriorityQueue会自动对剩余对象进行处理,保证仍然是一个大根堆(小根堆)。

放入对象的顺序为35124,而通过取队头对象,打印出来的顺序为12345,符合从小到大的顺序。

结尾

在LeetCode做到 【347. 前 K 个高频元素】时,有用到PriorityQueue,由于是用堆实现的,所以在解“前n个”之类的问题时,可以将对象放入堆中,然后用取堆顶对象的方法来实现。

发布了5 篇原创文章 · 获赞 0 · 访问量 57

猜你喜欢

转载自blog.csdn.net/weixin_41276957/article/details/104342145