目录
比较两个自定义类型是否相等,覆写object中的equals()方法
堆
堆逻辑上首先是一棵完全二叉树
大根堆/大堆:堆中根节点值 >= 子树的节点值,叫做大堆/大根堆/最大堆
小根堆/小堆:堆中根节点值 <= 子树的节点值,叫做小堆/大根堆/最大堆
注意
在最大堆中,当前的根节点是最大的,在任意子树中也满足
节点的大小关系和所处的层次无关
二叉树的存储方式
使用数组保存二叉树结构,将二叉树用层序遍历方式放入数组中
使用顺序表存储完全二叉树时,节点的索引和节点的关系如下:
根节点从0开始编号,已知父节点为k,左子树索引为2k+1,右子树索引为2k+2
已知子节点为k,父节点就是(k-1)/ 2
优先级队列
优先级队列处理的元素是动态变化的,有进有出
JDK中的优先级队列默认是最小堆的实现,队首就是当前队列的最小值
-
比较两个自定义类型是否相等,覆写object中的equals()方法
class Student {
String name;
int age;
public boolean equals(Object o){
if (o == null){
return false;
}
if (this == o){
return true;
}
//判断传入的o是否是一个类的实例
if (!(o instanceof Student)){
return false;
}
Student student = (Student) o;
return this.age == student.age && this.name.equals(student.name);
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
-
比较两个自定义的对象大小,覆写Comparable接口
java.lang.Comparable返回一个int值
返回值<0时,当前对象<传入对象
返回值=0时,当前对象=传入对象
返回值>0时,当前对象>传入对象
class Student implements Comparable<Student> {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
}
public class Test {
public static void main(String[] args) {
Student stu1 = new Student("张三",18);
Student stu2 = new Student("李四",29);
Student stu3 = new Student("王五",20);
System.out.println(stu1.compareTo(stu2));//-11
System.out.println(stu2.compareTo(stu1));//11
}
}
- 当覆写Comparable接口之后,就可以进行排序
public class Test {
public static void main(String[] args) {
Student stu1 = new Student("张三",18);
Student stu2 = new Student("李四",29);
Student stu3 = new Student("王五",20);
Student[] stu = new Student[] {stu1,stu2,stu3};
Arrays.sort(stu);
//[Student{name='张三', age=18}, Student{name='王五', age=20}, Student{name='李四', age=29}]
System.out.println(Arrays.toString(stu));
}
}
- 排序默认是升序排列,如果需要降序排列,需要修改compareTo()方法
public int compareTo(Student o) {
return o.age - this.age;
}
- 此时,就得到了降序排列
public class Test {
public static void main(String[] args) {
Student stu1 = new Student("张三",18);
Student stu2 = new Student("李四",29);
Student stu3 = new Student("王五",20);
Student[] stu = new Student[] {stu1,stu2,stu3};
Arrays.sort(stu);
//[Student{name='李四', age=29}, Student{name='王五', age=20}, Student{name='张三', age=18}]
System.out.println(Arrays.toString(stu));
}
}
-
Comparator比较器
Comparator比Comparable更灵活,不需要修改类中的代码
public class Test {
public static void main(String[] args) {
Student stu1 = new Student("张三",18);
Student stu2 = new Student("李四",29);
Student stu3 = new Student("王五",20);
Student[] stu = new Student[] {stu1,stu2,stu3};
Arrays.sort(stu, new StudentCom());
//[Student{name='张三', age=18}, Student{name='王五', age=20}, Student{name='李四', age=29}]
System.out.println(Arrays.toString(stu));
Arrays.sort(stu,new StudentDesc());
//[Student{name='李四', age=29}, Student{name='王五', age=20}, Student{name='张三', age=18}]
System.out.println(Arrays.toString(stu));
}
}
class StudentCom implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
}
}
class StudentDesc implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o2.getAge()-o1.getAge();
}
}
- 使用Comparator将JDK的最小堆改造为最大堆
public class PriorityQueueTest {
public static void main(String[] args) {
//通过构造方法传入比较器
Queue<Student> queue = new PriorityQueue<>(new StudentCom());
Student stu1 = new Student("张三",18);
Student stu2 = new Student("李四",29);
Student stu3 = new Student("王五",20);
queue.offer(stu1);
queue.offer(stu2);
queue.offer(stu3);
while (!queue.isEmpty()){
System.out.println(queue.poll());
//Student{name='张三', age=18}
//Student{name='王五', age=20}
//Student{name='李四', age=29}
}
}
}
- 当需要降序时,将 Queue<Student> queue = new PriorityQueue<>(new StudentCom());中的加粗部分改为
Queue<Student> queue = new PriorityQueue<>(new StudentDesc());
- 也可以这样写,匿名内部类,就是创建一个Comparator接口的子类,这个子类只使用一次
Queue<Student> queue = new PriorityQueue<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.getAge() - o1.getAge();
}
});
- 也可以这样写,Lambda表达式,函数式编程
Queue<Student> queue = new PriorityQueue<>((o1,o2) -> o2.getAge() - o1.getAge());
==和equals的区别
- ==
比较的是两者的值是否相等,如果比较的是两个基本类型,就是比较两个的数值是否相等。如果比较的是引用类型,要比较的是引用类型保存的地址
- equals
比较两个对象是否相等,可以自己定义
public class Test{
public static void main(String[] args){
Object o =new Object(){
public boolean equals(Object obj){
return true;
}
};
//true
System.out.println(o.equals("“”"));
//true
System.out.println(o.equals(123));
}
}
在匿名内部类中覆写equals方法,不进行比较,是直接返回true的
Comparable和Comparator的区别
当一个类实现了Comparable接口,那么这个类就具备了比较两个对象的能力,但是Comparator是把两个对象的比较交给另外一个类,当前类是没有比较的能力的