JAVA中的PriorityQueue优先队列的使用和比较器。

15 篇文章 0 订阅

直接上操作。

1。使用默认比较器

PriorityQueue<int[]> pq=new PriorityQueue<>();

上面这段代码是建立了一个优先队列,在泛型<>中可以看到int[],这表示队列中的每个元素都是一个int型数组。使用了不带参数的构造方法来创建实例,表示使用了默认的比较方法。元素自己自行比较。

2。使用自定义的比较器

下面这段代码摘自廖雪峰老师的java教程中。

https://liaoxuefeng.com/books/java/collection/priority-queue/

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;

public class Main {
    public static void main(String[] args) {
        Queue<User> q = new PriorityQueue<>(new UserComparator());
        // 添加3个元素到队列:
        q.offer(new User("Bob", "A1"));
        q.offer(new User("Alice", "A2"));
        q.offer(new User("Boss", "V1"));
        System.out.println(q.poll()); // Boss/V1
        System.out.println(q.poll()); // Bob/A1
        System.out.println(q.poll()); // Alice/A2
        System.out.println(q.poll()); // null,因为队列为空
    }
}

class UserComparator implements Comparator<User> {
    public int compare(User u1, User u2) {
        if (u1.number.charAt(0) == u2.number.charAt(0)) {
            // 如果两人的号都是A开头或者都是V开头,比较号的大小:
            return u1.number.compareTo(u2.number);
        }
        if (u1.number.charAt(0) == 'V') {
            // u1的号码是V开头,优先级高:
            return -1;
        } else {
            return 1;
        }
    }
}

class User {
    public final String name;
    public final String number;

    public User(String name, String number) {
        this.name = name;
        this.number = number;
    }

    public String toString() {
        return name + "/" + number;
    }
}

看到User类,这是我们存入这个优先队列中的元素。

看到UerComparator类,这是我们编写比较器的类,它实现了Comparator接口,必须要实现Comparator接口中的compare方法。

看到创建PriorityQueue实例,在其中我们传入了创建的比较器的类的实例,因为PriorityQueue默认是使用Comparator接口的compare方法,所以PriorityQueue会找到该实例中的compare方法覆盖默认的compare方法作为新的比较器。

看到比较器类的compare方法,有两个参数,记住,第一个参数永远是新的参数,插入的时候就是插入的参数,删除的时候就是被删除的参数,然后第二个参数就是依次与之比较的参数。其中的逻辑是compare返回时负值的时候,表示要交换,否则表示不要交换。所以默认是小根堆,如果传入进来的是小的元素,则不断比较的过程中,会进行不断地交换。

小顶堆, return 前减后(o1-o2);
大顶堆, return 后减前(o2-o1);

由于PriorityQueue是使用大根堆或者小根堆实现的,所以该比较器是用来在创建堆的时候判断大小来移动元素用的,具体逻辑可以自行去结合堆排序来思考。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值