优先级队列

简介: 优先级队列

优先级队列


优先级队列是一种先进先出的数据结构,操作的数据带有优先级,这种数据结构就是优先级队列(PriorityQueue),优先级队列是一种先进先出(FIFO)的数据结构,与队列不同的是,操作的数据带有优先级,通俗的讲就是可以比较大小,在出队列的时候往往需要优先级最高或者最低的元素先出队列,这种数据结构就是优先级队列(PriorityQueue)。

不能插入null对象,否则会抛NullPointerException异常


PriorityQueue底层使用堆数据结构


PriorityQueue默认是小堆,如果想要创建大堆可以使用比较器


        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });

o2-o1是创建大堆,o1-o2是创建小堆


JDK1.8中PriorityQueue底层采用了堆数据结构,堆其实就是对完全二叉树的元素作出了一些调整

所谓堆就是将一组数据按照完全二叉树的顺序存储方式存储,保证每一个根结点元素大于它的孩子结点的元素(大根堆)或者小于它的孩子结点的元素(小根堆),堆中某个结点的值总是不大于或着不小于其父节点的值。堆是一颗完全二叉树。


比较器


Comparable和Comparator都是两个接口,接口都可以用来实现集合中元素的比较、排序,Comparator位于包java.util下,而Comparable位于包java.lang下,Comparable接口将比较代码嵌入自身类中,而Comparator既可以嵌入到自身类中,也可以在一个独立的类中实现比较。

Integer、String等这些基本类型的JAVA封装类都已经实现了Comparable接口,这些类对象本身就支持自比较,直接调用Collections.sort()就可以对集合中元素的排序,无需自己去实现Comparable接口。而有些自定义类的List序列,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较,也就是指定使用Comparator(临时规则排序,也称作专门规则排序),如果不指定Comparator,那么就用自然规则排序,这里的自然顺序就是实现Comparable接口设定的排序方式。


Top-k问题

求前k个最大,建小堆

求前k个最小,建大堆

代码示例

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

输入: nums = [1,1,1,2,2,3], k = 2

输出: [1,2]

 public int[] topKFrequent(int[] nums, int k) {
        Map<Integer,Integer> map=new HashMap<>();
        for (int num : nums) {
            int orDefault = (int) map.getOrDefault(num, 0);
            map.put(num,orDefault+1);
        }
//        PriorityQueue<Map.Entry<Integer, Integer>> queue=new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {
//            @Override
//            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
//                return o1.getValue()-o2.getValue();
//            }
//        });
        PriorityQueue<Map.Entry<Integer, Integer>> queue=new PriorityQueue<>((o1, o2) -> o1.getValue()-o2.getValue());
        for (Map.Entry<Integer, Integer> integerIntegerEntry : map.entrySet()) {
            queue.add(integerIntegerEntry);
            if(queue.size()>k)
                queue.poll();
        }
        System.out.println(queue);
        int[] dp=new int[k];
        for(int i=k-1;i>=0;i--){
            dp[i]=queue.poll().getKey();
        }
        return dp;
    }
Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现
public class Person implements Comparable<Person>{
    private String username;
    private Integer age;
    @Override
    public int compareTo(Person o) {
        return this.age-o.age;
    }
}


相关文章
|
6月前
堆(优先级队列 PriorityQueue)
堆(优先级队列 PriorityQueue)
41 0
|
存储 安全 索引
认真研究队列中的优先级队列PriorityQueue
认真研究队列中的优先级队列PriorityQueue
75 0
|
Java 调度
【PriorityQueue优先级队列及其应用】
【PriorityQueue优先级队列及其应用】
|
6月前
|
存储 Java
优先级队列(堆)
优先级队列(堆)
45 3
|
3月前
|
存储 设计模式 算法
【C++】deque以及优先级队列
【C++】deque以及优先级队列
|
5月前
|
C++ 容器
【C++】学习笔记——优先级队列
【C++】学习笔记——优先级队列
41 0
|
6月前
|
存储 安全 Java
优先级队列
优先级队列
|
6月前
|
存储 算法 安全
堆 和 优先级队列(超详细讲解,就怕你学不会)
堆 和 优先级队列(超详细讲解,就怕你学不会)
|
6月前
|
存储 安全
堆与优先级队列
堆与优先级队列
37 0
|
6月前
|
存储 Java C++
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
55 0