比较器 Comaprator,经典的多元素协同排序,大厂笔试必考1题

本文详细介绍了如何使用比较器Comparator实现自定义排序,包括基础的升序和降序排序,以及如何创建协同比较器进行多条件排序。在大厂笔试中,这种题目常见,例如华为、字节跳动等公司。通过实例展示了如何对学生对象按年龄和学号进行协同排序,并提供了相应的代码实现。
摘要由CSDN通过智能技术生成

比较器 Comaprator,经典的多元素协同排序,大厂笔试必考1题

提示:在大厂的笔试题中,贪心的题目,经常考,比如华为,字节,美团等等,都会考协同排序,比较器来玩


啥是比较器协同排序

就你自己设计的数据结构,不是系统基础类,比如学生类Student
学生有姓名,学号,年龄等属性

public static class Student{
        private String name;
        private String ID;
        private int age;
        public Student(String n, String i, int a){
            name = n;
            ID = i;
            age = a;
        }
    }

现在需要你给一堆学生排序,排序规则是:
(1)当年龄不同时,按照年龄升序排序
(2)当年龄相同时,按照学号升序排序

——这就是我们讲的协同排序


比较器本质

我们先看比较器,怎么给其中1个属性排序
比如年龄:
写一个自己的比较器:myComparator2,执行一个接口:Comparator
里面操作的数据类型是Student
——如果比较函数是:比较2个Student :o2和o1:
return o2.age - o1.age;//根据年龄降序排
这等价于:降序排序,o2排在前面。
本质是:
(1)如果o2.age - o1.age < 0 ,则返回-1;代表o2.age小于o1.age
(2)o2.age - o1.age = 0,则返回0,代表o2.age=o1.age
(3)o2.age - o1.age > 0,则返回1,代表o2.ag>于o1.age

面对return o2.age - o1.age;//根据年龄降序排
此时我们的o2是排在o1前面的,我们要让比较器恰好返回1,故是降序排列。

——如果比较函数是:比较2个Student :o1和o2:
return o1.age - o2.age;//根据年龄降升序排
这等价于:降序排序,o2排在前面。
本质是:
(1)如果o1.age - o2.age < 0 ,则返回-1;代表o1.age小于o2.age
(2)o1.age - o2.age = 0,则返回0,代表o1.age=o2.age
(3)o1.age - o2.age > 0,则返回1,代表o1.ag>于o2.age

面对return o1.age - o2.age;//根据年龄降升序排
此时我们的o1是排在o2前面的,我们要让比较器恰好返回-1,故是升序排列。

在这里插入图片描述

//降序排列比较器的写法
public static class myComparator2 implements Comparator<Student>{
        @Override
        public int compare(Student o1, Student o2){
            return o2.age - o1.age;//根据年龄降序排
        }
    }
//升序排列比较器的写法
    public static class upComparator implements Comparator<Student>{
        @Override
        public int compare(Student o1, Student o2){
            return o1.age - o2.age;
        }
    }

我们怎么用呢?
有几个学生,我们来个根据升序和降序排序

//Student类型的
    public static void test2(){
        Student stu = new Student("a", "1", 1);
        Student stu2 = new Student("b", "2", 2);
        Student stu3 = new Student("c", "3", 3);
        PriorityQueue<Student> heap = new PriorityQueue<>(new myComparator2());
        PriorityQueue<Student> heap2 = new PriorityQueue<>(new upComparator());
        //挨个加入大根堆,降序,就是大根堆,默认小根堆
        heap.add(stu);
        heap.add(stu2);
        heap.add(stu3);
        System.out.println(heap.peek().age);//头顶的年龄
        //这个大根堆,小根堆的思想要记住,堆结构比堆排序重要

		//小根堆
        heap2.add(stu);
        heap2.add(stu2);
        heap2.add(stu3);
        System.out.println(heap2.peek().age);//头顶的年龄
    }
    public static void main(String[] args) {
        test2();
    }

结果:

3
1

基础数据类型也可以写

比如int的降序

//单存的int类型的降序比较器
    public static class myComparator implements Comparator<Integer>{

        @Override
        public int compare(Integer o1, Integer o2) {
            return o2 - o1;//降序
        }
    }

    public static void test1(){
        PriorityQueue<Integer> heap = new PriorityQueue<>(new myComparator());
        //这里new就是提醒为大根堆
        heap.add(1);
        heap.add(2);
        heap.add(3);
        System.out.println(heap.peek());
    }

协同比较器排序

现在需要你给一堆学生排序,排序规则是:
(1)当年龄不同时,按照年龄升序排序
(2)当年龄相同时,按照学号升序排序

——这就是我们讲的协同排序

联合的话,直接写一个比较器也就可以了,这么写
分条件返回
当(1)满足,就返回(1)
当(1)不满足,咱再写(2)

//复习协同比较器排序;
    //(1)当年龄不同时,按照年龄升序排序
    //(2)当年龄相同时,按照学号升序排序
    public static class cooperateComparator implements Comparator<Student>{
        @Override
        public int compare(Student o1, Student o2){
            return o1.age != o2.age ? o1.age - o2.age : o1.ID.compareTo(o2.ID);
        }
    }
    //测试
    public static void test3(){
        Student stu = new Student("a", "20181214192", 1);
        Student stu2 = new Student("b", "20181214193", 2);
        Student stu3 = new Student("c", "20181214190", 2);
        PriorityQueue<Student> heap = new PriorityQueue<>(new cooperateComparator());
        //协同排序
        heap.add(stu);
        heap.add(stu2);
        heap.add(stu3);
        while (!heap.isEmpty()){
            System.out.println(heap.poll().name);
        }
    }


    public static void main(String[] args) {
//        test2();
        test3();
    }

测试:

a
c
b

显然,a用户,它的年龄最小,故,排在最左
b和c年龄一样,但是c的ID字符串的字典序更小,所以就c排在b前面


总结

提示:重要经验:

1)比较器的本质,返回3种值,-1,0,1,但是o1在前,认为是升序,小根堆,o2在前,认为是降序,大根堆
2)在互联网大厂的笔试中,经常考比较器,尤其想华为这种个,需要配置硬件资源,服务器的各种参数选择有先后顺序,就需要设计协同排序,协同比较器就是最常用的数据结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰露可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值