排序演算法——簡單選擇排序
阿新 • • 發佈:2019-02-07
選擇排序基本思想
在要排序的一組數中,選出最小(或者最大)的一個數與第1個位置的數交換;然後在剩下的數當中再找最小(或者最大)的與第2個位置的數交換,依次類推,直到第n-1個元素(倒數第二個數)和第n個元素(最後一個數)比較為止。
對陣列{ 8, 5, 2, 6, 9, 3, 1, 4, 0, 7 }排序。
選擇排序是不穩定的排序演算法,在一趟選擇,如果一個元素比當前元素小,而該小的元素又出現在一個和當前元素相等的元素後面,那麼交換後穩定性就被破壞了。 比如序列:{ 3, 7, 3, 2, 6 },一次選擇的最小元素是2,然後把2和第一個3進行交換,從而改變了兩個元素3的相對次序。
java程式碼實現:
package com.lilin.utils;
import java.util.Arrays;
/**
* 選擇排序
*
* @author lilin
*
*/
public class SelctionSort {
/*
* 實現原理
* 在要排序的一組數中,選出最小(或者最大)的一個數與第1個位置的數交換;然後在剩下的數當中再找最小(或者最大)的與第2個位置的數交換,依次類推,
* 直到第n-1個元素(倒數第二個數)和第n個元素(最後一個數)比較為止。
*/
/**
* 簡單選擇排序演算法
*
* @param array
* 陣列
* @param n
* 排序陣列的前n個數,當n=array.length則表示排序整個陣列。
*/
public static void selectSort(int array[], int n) {
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
//此處可以將交換順序的程式碼抽取出來,在這裡主要論原理,就不抽取了。
if (minIndex != i) {
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
System.out.println("第" + (i + 1) + "次排序結果" + Arrays.toString(array));
}
System.out.println("選擇排序好陣列" + Arrays.toString(array));
}
}
選擇排序平均時間複雜度:O(n²)
選擇排序的交換操作介於 0 和 (n - 1) 次之間。選擇排序的比較操作為 n (n - 1) / 2 次之間。選擇排序的賦值操作介於 0和 3 (n - 1) 次之間。
比較次數O(n²),比較次數與關鍵字的初始狀態無關,總的比較次數N=(n-1)+(n-2)+…+1=n*(n-1)/2。交換次數O(n),最好情況是,已經有序,交換0次;最壞情況交換n-1次,逆序交換n/2次。交換次數比氣泡排序少多了,由於交換所需CPU時間比比較所需的CPU時間多,n值較小時,選擇排序比氣泡排序快。(氣泡排序見後續博文)
上述演算法的一輪的比較中,只取出一個最小值,如果在一輪比較中,同時將最小值和最大值取出,分別和參與比較的陣列中首尾位置交換位置,則可以減少一般比較次數。
具體實現如下
package com.lilin.utils;
import java.util.Arrays;
/**
* 選擇排序
*
* @author lilin
*
*/
public class SelctionSort {
/**
* 升級版選擇排序演算法(找出最大值和最小值)
*
* @param array
* 陣列
* @param n
* 比較陣列的前n個數,當n=array.length則表示排序整個陣列。
*/
public static void selectSortUpgrade(int array[], int n) {
for (int i = 0; i <n/2; i++) {
int minIndex = i;//記錄最小值位置
int maxIndex = i;// 記錄最大關鍵字位置
for (int j = i+1; j <n-i; j++) {
if (array[j] > array[maxIndex]) {
maxIndex = j;
}
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
//此處可以將交換順序的程式碼抽取出來,在這裡主要論原理,就不抽取了。
if (minIndex != i) {
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
if (maxIndex != n - i-1) {
int temp = array[n - i-1];
array[n -i-1] = array[maxIndex];
array[maxIndex] = temp;
}
System.out.println("第" + (i + 1) + "次排序結果" + Arrays.toString(array));
}
System.out.println("選擇排序好陣列" + Arrays.toString(array));
}
}