优先级队列 PriorityQueue

1. 优先级队列是什么??

首先,优先级队列是一个队列,队列所有的性质,它也有。

其次,优先级队列每次取出的是优先级最高的元素。

优先级队列的内部是用来维护的。将优先级最高的排在前面。

2. 什么时候用这个队列呢??

看完优先级队列的定义,好像看懂了,又好像没看懂。这队列,什么用它呢?

1)排序的对象和排序时比较的对象

常见的排序方法(插入、快排等),排序的对象和比较的对象是一样的,根据数本身的大小进行排序。

优先级队列可以对排序对象和比较对象相同的进行排序,也可以对 排序的对象和排序时比较的对象不同 的进行排序。

排序的对象和排序时比较的对象不同的一种情况是对 Map 排序。 在 Map 中,按照值 ValueKey 进行排序。这时,排序的对象是 Key ,比较的对象是 Value

2)堆

优先级队列的内部是用来维护的。所以,也可以把优先级队列当做堆来用。需要用堆的时候,用优先级队列试试看。

3. 对一数组排序

int[] arr = {3, 7, 5, 1, 8};
PriorityQueue<Integer> queue = new PriorityQueue<>();
for (int t : arr) {
    queue.offer(t);
    System.out.println("queue = " + queue);
}

输出结果:

queue = [3]
queue = [3, 7]
queue = [3, 7, 5]
queue = [1, 3, 5, 7]
queue = [1, 3, 5, 7, 8]

queue = [3, 7, 5] 可以看出,在排序时,queue 虽然也是按照整数的自然序来排的,但是不是按照递增的顺序(队列中的元素并不是一直是递增排列),是按堆存放的。

下面,将优先级队列的大小设置为3,看一下优先级队列的变化

int[] arr = {3, 7, 5, 1, 8};
PriorityQueue<Integer> queue = new PriorityQueue<>();
for (int cur : arr) {
    queue.offer(cur);
    if (queue.size() > 3){
        int t = queue.poll();
        System.out.print("poll = " + t);
    }
    System.out.println("queue = " + queue);
}

输出结果:

queue = [3]
queue = [3, 7]
queue = [3, 7, 5]
poll = 1 queue = [3, 7, 5]
poll = 3 queue = [5, 7, 8]

从结果中可以看出,每次弹出的是最小的值。

4. Map 按值排序

有两种方案实现 Map 根据值 Value 对键 Key 排序:

  • 队列中存 key
  • 队列中存 Map.entry

4.1 队列中存 key

Map<Integer, Integer> map = new HashMap<>();
// map 中存入值,这里不再写

// 创建优先级队列,同时定义比较规则
PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){
    public int compare(Integer a, Integer b) {
        return map.get(a) - map.get(b);  // 按值 Value 升序排
    }
});

// 加入队列,并排序
for (Integer key: map.keySet()) {
    queue.offer(key);  // 加入队列的同时,会排序
}

/*************************************************************************/
// 创建优先级队列时,还可以简化为下面的方式
PriorityQueue<Integer> queue = new PriorityQueue<>((a, b) -> {
    return map.get(a) - map.get(b);
});

4.2 队列中存 Map.entry

Map 中的 <key,value> 看作一个整体,通过 Map.entry<> 就可以取出。与上面一种方法的不同就是,把 Integer 变成了 Map.entry<Integer, Integer> ,其他的,暂时没看出来。

Map<Integer, Integer> map = new HashMap<>();
// map 中存入值,这里不再写

// 创建优先级队列,同时定义比较规则
PriorityQueue<Map.entry<Integer, Integer>> queue = new PriorityQueue<>((a, b) -> {
    return a.getValue() - b,getValue();
});

// Set<Map.entry<Integer, Integer>> set = map.entrySet();
// 加入队列,并排序
for (Map.entry<Integer, Integer> entry: map.entrySet()) {
    queue.offer(entry);  // 加入队列的同时,会排序
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值