【算法】排序(四)歸並排序
上次給大家說了說簡單的冒泡排序,這次我們來說一說插入排序
插入排序的做法就像是我們日常生活中玩撲克牌一樣,每次抽一張牌,將撲克牌按一定順序插入手牌中,一步步完成排序
本文將介紹以下內容
排序思想
算法實現(JAVA)
測試階段
排序過程講解
算法分析
排序思想
插入排序同樣有內循環和外循環,外循環執行n - 1次,內循環負責比較相鄰兩個數的大小並交換(如果需要)。每次將未排序序列裏的第一個數與後一個數比較,如果後者小,就交換二者的位置,並和以排序的序列元素依次比較並交換(如果需要)。
就如同玩撲克牌,每次抽取的一張牌都要與所有手牌一對一比較,並確定最終插入的位置。
算法實現
1. 外循環
public static void insertionSort(int[] a) {
int n = a.length;
for (int i = 1; i < n; i++) {
}
}
循環次數為n - 1,否則數組下標越界,下文會說明原因。
2. 內循環
for (int j = i; j > 0 && a[j] < a[j - 1] ; j--) { int temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; }
交換條件為後一項小於前一項,每次都是a[j]與a[j - 1] 比較,所以只能有n - 1 次循環,否則數組下標越界。
所以,插入排序的代碼塊就是如此了:
public static void insertionSort(int[] a) { int n = a.length; for (int i = 1; i < n; i++) { for (int j = i; j > 0 && a[j] < a[j - 1] ; j--) { int temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } } }
測試階段
我們還是用十個隨機數字來作為輸入:
public static void main(String[] args){
int[] a = new int[10];
for (int i = 0; i < a.length; i++) {
a[i] = (int)(Math.random()*100);
System.out.print(a[i] + " ");
}
System.out.println();
insertionSort(a);
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
隨機選取幾組結果:
排序過程講解
我們以result_1的排序結果作為示例來解釋一下排序過程:
第一步:74與11比較,交換順序,已排序序列為[11,74]
第二步:74與99比較,不交換順序,已排序序列為[11,74,99]
第三步:99與85比較,交換順序,85與74比較,不交換順序,已排序序列為[11,74,85,99]
第四步:99與14比較,交換順序,85與14比較,交換順序,74與14比較,交換順序,已排序序列為[11,14,74,85,99]
第五步:99與74比較,交換順序,85與74比較,交換順序,74與74比較,不交換順序,已排序序列為[11,14,74,74,85,99]
第六步:99與24比較,交換順序,85與24比較,交換順序,74與24比較,交換順序,74與24比較,交換順序,14與24比較,不交換順序,已排序序列為[11,14,24,74,74,85,99]
第七步:99與90比較,交換順序,85與90比較,不交換順序,已排序序列為[11,14,24,74,74,85,90,99]
第八步:99與比54較,交換順序,85與54比較,交換順序,74與53比較,交換順序,74與54比較,交換順序,24與54比較,不交換順序,已排序序列為[11,14,24,54,74,74,85,99]
第九步:99與82比較,交換順序,85與82比較,交換順序,
74與82比較,不交換順序,已排序序列為[11,14,24,74,74,85,90,99]
n個元素的數組,經歷n - 1次排序,總而言之,如果兩元素比較,後者較小,就有可能多次比較,最後插入較前的位置。
算法分析
1. 特點
- 插入排序對於較為有序(部分有序)的數組時極為高效,因為有序的兩個數不滿足內循環的循環條件,所以可以直接跳過,極大增加效率。
2. 時間復雜度
最優情況:數組全部按升序排列,只需要進行n - 1次的比較就可完成,不需要交換
最差情況:數組全部按降序排列,需要進行n(n - 1) / 2次比較
(1 + 2 + 3 + ... + n - 1) = n(n - 1) / 2,需要進行n(n - 1) / 2次交換正常來說,插入排序的時間復雜度為O(n2)
3. 空間復雜度
插入排序需要一個臨時變量來交換元素,所以空間復雜度為O(1)
4. 穩定性
插入排序是穩定的,例如result_1中,排序前a[0] = a[5] = 74,且a[0]代表的74在a[5]代表的74之前。在排序過程中,兩個74相遇,並沒有交換位置,所以插入排序是穩定的
插入排序就講到這,下一篇文章將會是歸並排序。
【算法】排序(四)歸並排序