上一篇詳述了冒泡排序及其優化,有興趣的能夠看看:html
如何優化冒泡排序?java
如圖所示,每一趟找到未排序的最小值,並放到有序序列的後面(即當前趟對應於數組中的第幾個元素)。算法
private static <T extends Comparable<? super T>> void selectionSort(T[] nums) {
if (null == nums || nums.length == 0) {
throw new RuntimeException("數組爲null或長度爲0");
}
int length = nums.length;
int minValueIndex = 0;
T temp = null;
for (int i = 0; i < length - 1; i++) {
minValueIndex = i;
for (int j = i + 1; j < length; j++) {
if (nums[j].compareTo(nums[minValueIndex]) < 0) {
minValueIndex = j;
}
}
if (minValueIndex != i) {
temp = nums[i];
nums[i] = nums[minValueIndex];
nums[minValueIndex] = temp;
}
}
}
算法思想:經過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。插入排序於是在從後向前掃描過程當中,須要反覆把已排序元素逐步向後挪位,爲最新元素提供插入空間。數組
排序過程:(默認升序)app
InsertionSort 和打撲克牌時,從牌桌上逐一拿起撲克牌,在手上排序的進程相同。優化
舉例:spa
Input: {4, 3, 8, 5, 2, 6, 1, 7}。code
首先拿起第一張牌, 手上有 {4}。orm
拿起第二張牌 3, 把 3insert 到手上的牌 {4}, 獲得 {3 ,4}。htm
拿起第三張牌 8, 把 8 insert 到手上的牌 {3,4 }, 獲得 {3 ,4,8}。
以此類推。
插入排序由N-1趟排序組成。對於p=1到N-1趟排序後,插入排序保證從位置0到位置p上的元素爲已排序狀態。即插入排序利用了從位置0到p-1位置上已經有序的條件,將位置p上的元素向前查找適當的位置插入此元素。
如圖所示:在第p趟,咱們將位置p上的元素向左移動,直到它在前p+1個元素(包括當前位置的元素)中的正確位置被找到。
java實現插入排序
private static <T extends Comparable<? super T>> void insertSort(T[] nums) {
if (null == nums || nums.length == 0) {
throw new RuntimeException("數組爲null或長度爲0");
}
int length = nums.length;
T temp = null;
int i = 0;
for (int p = 1; p < length; p++) {
temp = nums[p];
for (i = p; i > 0 && (temp.compareTo(nums[i - 1]) < 0); i--) {
nums[i] = nums[i - 1];
}
nums[i] = temp;
}
}
時間、空間複雜度及穩定性分析:
選擇排序的主要優勢與數據移動有關。若是某個元素位於正確的最終位置上,則它不會被移動。選擇排序每次交換一對元素,它們當中至少有一個將被移到其最終位置上,所以對n個元素的表進行排序總共進行n-1次交換。在全部的徹底依靠交換去移動元素的排序方法中,選擇排序屬於很是好的一種。選擇排序最好、最壞時間複雜度都爲O(n^2),空間複雜度爲O(1),屬於不穩定排序。
插入排序不適合對於數據量比較大的排序應用。可是,若是須要排序的數據量很小,例如,量級小於千;或者若已知輸入元素大體上按照順序排列,那麼插入排序仍是一個不錯的選擇。插入排序最好時間複雜度爲O(n)、最壞時間複雜度爲O(n^2),空間複雜度爲O(1),屬於穩定排序。