工程中的综合排序算法
- 对于基本数据类型(int,float等),用快排。
因为快排的速度最快
- 对于自己定义的类型(class类),用归并排序。
因为归并排序是稳定的。
- 当样本量小于60时,用插入排序。
尽管插入排序的复杂度是 O ( N 2 ) O(N^{2}) O(N2),但是当样本量很小的时候,由于插入排序的常数项很小,所以很快
注:对于大规模的样本量排序,根据数据类型选择快排还是归并排序,然后对分割后的小样本量插入排序
有关排序问题的补充
- 归并排序的额外空间复杂度可以变成 O ( 1 ) O(1) O(1), 但是非常难,不需要掌握,可以搜“归并排序 内部缓存法”
- 快速排序可以做到稳定性,但是非常难,不需要掌握,可以搜“01 stable sort”。
比较器
package basic_class_01;
import java.util.Arrays;
import java.util.Comparator;
/**
*
* 自定义排序规则
*
*/
public class Code_09_Comparator {
public static class Student {
public String name;
public int id;
public int age;
public Student(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
}
public static class IdAscendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.id - o2.id;
}
}
public static class IdDescendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o2.id - o1.id;
}
}
public static class AgeAscendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
public static class AgeDescendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o2.age - o1.age;
}
}
public static void printStudents(Student[] students) {
for (Student student : students) {
System.out.println("Name : " + student.name + ", Id : " + student.id +
", Age : " + student.age);
}
System.out.println("===========================");
}
public static void main(String[] args) {
Student student1 = new Student("A", 1, 23);
Student student2 = new Student("B", 2, 21);
Student student3 = new Student("C", 3, 22);
Student[] students = new Student[] { student3, student2, student1 };
printStudents(students);
Arrays.sort(students, new IdAscendingComparator());
printStudents(students);
Arrays.sort(students, new IdDescendingComparator());
printStudents(students);
Arrays.sort(students, new AgeAscendingComparator());
printStudents(students);
Arrays.sort(students, new AgeDescendingComparator());
printStudents(students);
}
}
- 分析:
其中,IdAscendingComparator 比较器实现代码为:
public static class IdAscendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.id - o2.id;
}
}
其实,最原始的写法应为:
public static class IdAscendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
if(o1.id < o2.id) {
// 如果返回负数,那么o1排在前面,加上o1.id < o2.id,就说明这是升序排列
return -1;
} else if(o1.id > o2.id) {
// 如果返回整数,那么o2排在前面,加上o1.id > o2.id,就说明这是升序排列
return 1;
} else {
// 如果返回0,那么o1, o2相等
return 0;
}
}
}
一般常用简写:也就是
return o1.id - o2.id;
, 升序排列;return o2.id - o1.id;
,降序排列。
- 比较器的用处(有序结构中)
- 优先队列:
PriorityQueue<Student> heap = new PriorityQueue<>(new IdAscendingComparator());
构造优先队列时的优先级是按照IdAscendingComparator
定义的。 - 红黑树:
TreeSet<Student> treeSet= new TreeSet<>(new IdAscendingComparator());