1、簡單選擇排序java
描述:給定待排序序列A[ 0......n ] ,選擇出第i小元素,並和A[i]交換,這就是一趟簡單選擇排序。算法
示例:給定數組A[0 ...... 5]={3, 5, 8, 9, 1, 2},分析A數組進行選擇排序的過程:數組
第二趟:i=2,index=6, a[2] 和 a[6] 進行交換。獲得序列:{ 1,2,8,9,3,5 }函數
第三趟:i=3,index=5, a[3] 和 a[5] 進行交換。獲得序列:{ 1,2,3,9,8,5 }性能
第四趟:i=4,index=6, a[3] 和 a[5] 進行交換。獲得序列:{ 1,2,3,5,8,9 }spa
第五趟:i=5,index=5, 不用交換。獲得序列:{ 1,2,3,5,8,9 }code
6-1)趟選擇結束,獲得有序序列:{ 1,2,3,5,8,9 }orm
public class SimpleSelectionSort1 { void simpleSelectionSort(int[] arr) { int length = arr.length; int i, j, index; //1. 進行length-1趟選擇,每次選擇出最小值 for (i = 0; i < length; i++) { index = i; //2. 選擇第i小記錄爲arr[index] for (j = i+1; j < length; j ++) { if (arr[j] < arr[index]) { index = j; } } if (index != i) { arr[i] = arr[i] + arr[index]; arr[index] = arr[i] - arr[index]; arr[i] = arr[i] - arr[index]; } } printArray(arr); } void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } } public static void main(String[] args) { int[] arr = {9, 6, 12, 1, 15, 10, 17, 2, 11, 1, 4, 8, 19, 14}; SimpleSelectionSort1 selectionSort = new SimpleSelectionSort1(); selectionSort.simpleSelectionSort(arr); } }
import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; public class SimpleSelectionSort2 { public List<Integer> list = new ArrayList<Integer>(); /** * 遞歸函數進行簡單選擇排序--採用list存儲新排序的array,不太好 * @param arr 待排序的數組 */ void simpleSelectionSort(int[] arr) { int length = arr.length; int i, index; if (length == 1) { list.add(arr[0]); printArray(list); return; } //選擇序列中最小元素,下標爲index for (i = index = 0; i < length; i++) { if (arr[i] < arr[index]) { index = i; } } //將最小元素與序列中首元素交換 if (index != 0) { arr[0] = arr[0] + arr[index]; arr[index] = arr[0] - arr[index]; arr[0] = arr[0] - arr[index]; } list.add(arr[0]); //去除序列中的最小首元素,進行遞歸調用 arr = Arrays.copyOfRange(arr, 1, arr.length); simpleSelectionSort(arr); } /** * 遞歸函數進行簡單選擇排序 * @param array 待排序的數組 * @param startIndex 從startIndex數組下標開始日後排序,忽略startIndex以前的元素 */ public void simpleSelectionSortRecursion(int[] array, int startIndex){ //遞歸結束條件 if(startIndex == array.length - 1){ printArray(array); return; } //假設start元素爲最小值 int minIndex = startIndex; for(int i = startIndex; i < array.length; i++){ if(array[i] < array[minIndex]){ minIndex = i; } } //若是start元素就是最小值,則再也不交換 if (minIndex != startIndex) { array[startIndex] = array[startIndex] + array[minIndex]; array[minIndex] = array[startIndex] - array[minIndex]; array[startIndex] = array[startIndex] - array[minIndex]; } //遞歸:前面一位已經排序成功,排序startIndex元素日後移一位 simpleSelectionSortRecursion(array, startIndex + 1); } void printArray(List<Integer> array) { Iterator iterator = array.iterator(); while (iterator.hasNext()) { System.out.print(iterator.next() + " "); } } void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } } public static void main(String[] args) { int[] arr = {9, 6, 12, 1, 15, 10, 17, 2, 11, 1, 4, 8, 19, 14}; SimpleSelectionSort2 selectionSort2 = new SimpleSelectionSort2(); selectionSort2.simpleSelectionSort(arr); System.out.println("\n------------分割線--------------"); selectionSort2.simpleSelectionSortRecursion(arr, 0); } }
性能分析排序
容易看出,簡單選擇排序所需進行記錄移動的操做次數較少,這一點上優於冒泡排序,最佳狀況下(待排序序列有序)記錄移動次數爲0,最壞狀況下(待排序序列逆序)記錄移動次數n-1。遞歸
外層循環進行了n-1趟選擇,第i趟選擇要進行n-i次比較。每一趟的時間:n-i次的比較時間+移動記錄的時間(爲一常數0或1,能夠忽略)。總共進行了n-1趟。忽略移動記錄的時間,因此總時間爲(n-1)*(n-i)=n^2-(i+1)*n+i。時間複雜度爲O(n^2)。無論是最壞仍是最佳狀況下,比較次數都是同樣的,因此簡單選擇排序平均時間、最壞狀況、最佳狀況 時間複雜度都爲O(n^2)。同時簡單選擇排序是一種穩定的原地排序算法。固然穩定性仍是要看具體的代碼,在此就不作深究。