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 [email protected]
* @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 <[email protected]>
* @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;
}
}