1. 算法步骤
-
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
-
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
-
重复第二步,直到所有元素均排序完毕。
2. 动图演示
3 代码实现
基础选择排序
public class Selection {
/**
* 排序
* @param a
* @return
*/
public static Comparable [] sort(Comparable a[]){
if(Objects.isNull(a)) return null;
if(a.length < 2) return a;
for(int i = 0; i< a.length - 1; i++){ // 总共要比较n-1轮
int minIndex = i; // 初始默认当前索引所在数据为最小值
for(int j = i + 1; j < a.length; j++){ // 每轮要比较的次数
if(greater(a[minIndex], a[j])){ // 如果a[minIndex] > a[j]
minIndex = j;
}
}
if(minIndex != i){ // 最小不是当前项,交换位置
swap(a,minIndex, i);
}
}
return a;
}
/**
* 交换数据
* @param v
* @param i
* @param j
*/
public static void swap(Comparable v[], int i, int j){
Comparable temp = null;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
/**
* 比较两个数的大小
* @param v
* @param m
* @return
*/
public static boolean greater(Comparable v, Comparable m){
return v.compareTo(m) > 0;
}
}
优化后的选择排序
在上面例子中我们每次都找到最小值,只排定最小值。如果我们每次都找到最小值的时候,也把最大值找到,那么就能减少一半的遍历次数。
/**
* @Description 选择排序
* @Author jidi
* @Email jidi_jidi@163.com
* @Date 2020/6/10
*/
public class Selection {
/**
* 排序
* @param a
* @return
*/
public static Comparable [] sort(Comparable a[]){
if(Objects.isNull(a)) return null;
if(a.length < 2) return a;
for(int i=0; i< a.length - 1; i++){ // 总共要比较n-1轮
int minIndex = i; // 初始默认当前索引所在数据为最小值
for(int j = i + 1; j < a.length; j++){ // 每轮要比较的次数
if(greater(a[minIndex], a[j])){ // 如果a[minIndex] > a[j]
minIndex = j;
}
}
if(minIndex != i){ // 最小不是当前项,交换位置
swap(a,minIndex, i);
}
}
return a;
}
/** 优化后的选择排序
* @Description
* @Author jidi <jidi_jidi@163.com>
* @Since 2020/6/10
*/
public static Comparable[] sortPlus(Comparable[] arr) {
if(Objects.isNull(arr)) return null;
if(arr.length < 2) return arr;
for (int left = 0, right = arr.length - 1; left < right; left++, right--) {
int min = left; // 记录最小值
int max = right; // 记录最大值
for (int index = left; index <= right; index++) {
if (greater(arr[min], arr[index])) {
min = index;
}
if (greater(arr[index], arr[max])) {
max = index;
}
}
// 将最小值交换到 left 的位置
if(min != left){
swap(arr, left, min);
}
if (left == max) { // 如果最大值为left索引处,由于left索引处数据与min索引处数据交换了,此时要取min处索引处的数据
max = min;
}
// 将最大值交换到 right 的位置
if(max != right){
swap(arr, right, max);
}
}
return arr;
}
/**
* 交换数据
* @param v
* @param i
* @param j
*/
public static void swap(Comparable v[], int i, int j){
Comparable temp = v[i];
v[i] = v[j];
v[j] = temp;
}
/**
* 比较两个数的大小
* @param v
* @param m
* @return
*/
public static boolean greater(Comparable v, Comparable m){
return v.compareTo(m) > 0;
}
}