优先级队列和普通队列的区别:普通队列的元素就是先入先出的出队操作
优先级队列:表面是队列 底层是基于堆实现的 按照元素的优先级动态出队;
如果是基于最大堆的优先级队列 那么堆的值越大他的优先级越高 JDK中的优先级队列默认是最小堆的实现
import stack_queue.queue.Queue; public class PriorityQueue implements Queue<Integer> { private MaxHeap heap; public PriorityQueue() { heap = new MaxHeap(); } @Override public void offer(Integer val) { heap.add(val); } @Override public Integer poll() { return heap.extractMax(); } @Override public Integer peek() { return heap.peekMax(); }
package heap; /** * @author hututu * @date 2022/03/30 11:55 **/ import java.util.Comparator; import java.util.Queue; import java.util.PriorityQueue; import java.util.Arrays; public class PriorityQueueTest { public static void main(String[] args) { // 通过构造方法传入比较器 // 默认是最小堆,"值"(比较器compare的返回值)越小,优先级就越高 // 当传入一个降序的比较器时,值(比较器compare的返回值,值越大,返回负数) // Queue<Student> queue = new PriorityQueue<>(new StudentComDesc()); // Queue<Student> queue = new PriorityQueue<>(new Comparator<Student>() { // @Override // public int compare(Student o1, Student o2) { // return o2.getAge() - o1.getAge(); // } // }); Queue<Student> queue = new PriorityQueue<>((o1,o2) -> o2.getAge() - o1.getAge()); Student stu1 = new Student("铭哥",40); Student stu2 = new Student("龙哥",20); Student stu3 = new Student("蛋哥",18); Student[] students={stu1,stu2,stu3}; Arrays.sort(students,new StudentComDesc()); System.out.println(Arrays.toString(students)); // queue.offer(stu1); // queue.offer(stu2); // queue.offer(stu3); System.out.println(stu1.equals(stu2)); while (!queue.isEmpty()) { System.out.println(queue.poll()); } } } class StudentCom implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.getAge() - o2.getAge(); } } class StudentComDesc implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o2.getAge() - o1.getAge(); } } class Student { private String name; private int age; public int getAge() { return age; } public Student(String name, int age) { this.name = name; this.age = age; } // public boolean equals(Object o){ // if (o==null){ // return false; // } // if (this==o){ // return true; // } // //传入的o是否为student new出来的 // if(!(o instanceof Student)){ //强制类型转换 避免出错 // return false; // } // Student stu=(Student) o; // return this.age==stu.age&&this.name.equals(stu.name); // } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
元素间大小比较:当我们比较两个自定义类型是否相等=>覆写Object类提供的equals方法
比较两个自定义的对象谁大谁小 :java.lang.Comparable
一个类实现了comparable接口,就表示该类具备了可比较大小的能力
int >0 当前对象大于传入对象
=0当前对象=传入对象
<0当前对象小于传入对象
在sort方法内部,就是按照compareTo方法的返回值大小来进行排序的 默认是升序 大的在后面 小的在前 但也可以降序排 两个的comparaTo方法区别:
this.age-o.age o.age-this.age
但这种改来改去非常不方便 所以引入另一种比较器java.util.comparator
不需要实现接口 而是有一个专门的类实现此接口 Comparator相比较Comparable更加灵活 无侵入编程 也无需修改代码(当然用的话根据具体实现情况)
我们的操作系统的进程调度来说,(任务管理器)底层就维护了一个优先级队列
普通队列:入队:O(1)尾插 出队:O(n)
优先级队列(堆):入队 出队的时间复杂度都为log(n)
插一句:一般复杂度是log(n)的,近乎一定和“树”密切相关(此处不一定要构造出树结构,快排和归并的递归过程本质上是一个递归树,回溯算法大部分都是和logN相关的时间复杂度,回溯本质也是树)