思路:
插入排序法的思路與我們打撲克牌時排列手牌的方法很相似。就拿撲克牌舉例子,我們要單手拿牌,然后將牌從左至右,由大到小進行排序。此時我們需要將牌一張張抽出來,分別插入到前面已經排好序的手牌中的適當位置。重復這一操作直到插入最后一張牌,整個排序就完成了。
模版:
insertionSort(A, N)//包含N個元素的0起點數組A for i 從 1 到 N-1 v = A[i] j = i - 1 while j >= 0 且 A[j] >v A[j+1] = A[j] j-- A[j+1] = v _____________________________________ insertionSort(A, N) for( i = 1;i < N; i++) { v = A[i]; j = i - 1 ; while( j >=0&&A[j] > v) { A[j + 1] = A[j]; j--; } A[j + 1] = v; }
C++模板
#include <bits/stdc++.h> using namespace std; void insertionSort(int a[],int n) { int i,j,sum; for(i=1;i<n;i++) { sum=a[i]; j=i-1; while(j>=0&&a[j]>sum) { a[j+1]=a[j]; j--; } a[j+1]=sum; } } int main() { int n,i; cin>>n; int a[n]; for(i=0;i<n;i++) cin>>a[i]; insertionSort(a,n); for(i=0;i<n;i++) { cout<<a[i]; if(i!=n-1) cout<<" "; } cout<<endl; return 0; }
有關插入排序法的時間復雜度:
在插入排序法中,我們只將比v(取出的值)大的元素向后平移,不相鄰的元素不會直接交換位置,因此整個排序算法十分穩定。
然后我們考慮一下插入排序法的時間復雜度。這里需要估算每個 i 循環中A[ j ]元素向后移動的次數。最壞的情況下,每個 i 循環要執行 i 次移動,總共需要 1 + 2 +···+ N - 1=(N2 - N)/2次移動,即算法復雜度為O(N2)。
在計算復雜度的過程中,可以大致估計一下運算次數,然后只留下對代數式影響最大的項,忽略常數項。比如$\frac{N^2}{2}$-$\frac{N}{2}$,這里的N相對於N2而言就小得足以忽略,然后再忽略掉常數倍$\frac{1}{2}$,得出復雜度與N2成正比。當然,前提是假設這里的N足夠大。
插入排序法是一種很有趣的算法,輸入數據的順序能大幅度影響它的復雜度。我們前面說它的時間復雜度為O(N2),也僅是指輸入數據為降序排列的情況。如果輸入數據為升序排列,那么A[ j ]從頭至尾都不需要移動,程序只需要經過N次比較便可執行完畢。可見,插入排序法的優勢就在於能快速處理相對有序的數據。
例題:
請編寫一個程序,用插入排序法將包含N個元素的數列A按升序排列。程序中包含上述偽代碼所表示的算法。為檢驗算法的執行過程,請輸出各計算步驟的數組(完成輸入后的數組,以及每次 i 自增后的數組)。
輸入 :在第一行輸入定義數組長度的整數 N 。在第2行輸入 N 個整數,以空格隔開。
輸出 :輸出總共有 N 行。插入排序法每個計算步驟的中間結果各占用 1 行。數列的各元素之間空 1 個空格。請注意,行尾元素后的空格等多余的空格和換行會被認定為 Presentation Error。
限制 :1≤ N ≤100
0≤A的元素≤1000
輸入示例
6 5 2 4 6 1 3
輸出示例
5 2 4 6 1 3 2 5 4 6 1 3 2 4 5 6 1 3 2 4 5 6 1 3 1 2 4 5 6 3 1 2 3 4 5 6
C語言
#include <stdio.h> void trace(int A[],int N) { int i; for(i=0;i<N;i++) { if(i>0) printf(" "); printf("%d",A[i]); } printf("\n"); } void insertionSort(int A[],int N) { int j,i,v; for(i=1;i<N;i++) { v=A[i]; j=i-1; while (j>=0&&A[j]>v) { A[j+1]=A[j]; j--; } A[j+1]=v; trace(A,N); } } int main() { int N,i,j; int A[100]; scanf("%d",&N); for(i=0;i<N;i++) { scanf("%d",&A[i]); } trace(A,N); insertionSort(A,N); return 0; }
例題網址:
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_1_A