选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
选择排序实现代码
public class SelectionSort {
private SelectionSort(){}
public static <E> void sort(E[] arr){
for(int i=0;i<arr.length;i++){
int minIndex=i;
for(int j=i;j<arr.length;j++){
if(arr[j].compareTo(arr[minIndex])<0){
minIndex=j;
}
}
swap(arr,i,minIndex);
}
}
private static <E> void swap(E[] arr,int i,int j){
E t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
public static void main(String[] args) {
Integer[] data={1,3,5,2,4};
SelectionSort.sort(data);
for(int e:data){
System.out.print(e+" ");
}
System.out.println("");
Student[] students={ new Student("a",99),
new Student("b",66),
new Student("c",100)
};
SelectionSort.sort(students);
for(Student s:students){
System.out.print(s+" ");
}
System.out.println("");
}
}
使用带约束的泛型
由于选择排序算法要求待排序的数据元素是可比较的,所以我们需要对泛型进行一些限制,对应的方法就是使用带约束的泛型,在泛型后边加上extends Comparable,完善后的代码如下。
public class SelectionSort {
private SelectionSort(){}
public static <E extends Comparable<E>> void sort(E[] arr){
for(int i=0;i<arr.length;i++){
int minIndex=i;
for(int j=i;j<arr.length;j++){
if(arr[j].compareTo(arr[minIndex])<0){
minIndex=j;
}
}
swap(arr,i,minIndex);
}
}
private static <E> void swap(E[] arr,int i,int j){
E t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
public static void main(String[] args) {
Integer[] data={1,3,5,2,4};
SelectionSort.sort(data);
for(int e:data){
System.out.print(e+" ");
}
System.out.println("");
Student[] students={ new Student("a",99),
new Student("b",66),
new Student("c",100)
};
SelectionSort.sort(students);
for(Student s:students){
System.out.print(s+" ");
}
System.out.println("");
}
}
使用Comparable接口
在选择排序中数据元素的比较规则是可以由我们自己自定义的,这里我们以Student类为例,将学生按照分数从低到高排序,为了自定义比较规则,我们需要使用Comparable接口,具体代码如下。
public class Student implements Comparable<Student> {
private String name;
private int score;
public Student(String name,int score){
this.name=name;
this.score=score;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student student = (Student) o;
return score == student.score &&
name.equals(student.name);
}
@Override
public String toString() {
return String.format("Student(name:%s,score:%d)",name,score);
}
@Override
public int compareTo(Student o) {
return this.score-o.score;
}
}
换个角度实现选择排序
实现从后向前完成排序的选择排序算法,对应的循环不变量是arr[0,i)未排序,[i,n)已排序,具体代码如下
public static <E extends Comparable<E>> void sort(E[] arr){
for(int i=arr.length-1;i>=0;i--){
int maxIndex=i;
for(int j=i;j>=0;j--){
if(arr[j].compareTo(arr[maxIndex])>0){
maxIndex=j;
}
}
swap(arr,i,maxIndex);
}
}