1. 基本思想 算法
插入排序是對少許元素進行排序的有效算法。插入排序的過程很簡單,將待排序的表List分紅已排序和未排序的兩個部分(如圖1所示),將未排序中的元素依次插入已排序的表中。具體作法是取出未排序表中的一個元素,將之與已排序的表中元素依次進行比較,直至找到正確位置。則將該元素插入到該位置,重複這個步驟,直至未排序中元素所有插入已排序的表中。數組
(圖1)spa
2. 算法實現code
這裏使用模板來實現,以加強代碼的實用性。blog
1 template<class T> 2 void insert_sort(T* a,int n) 3 { 4 for(int i=1;i<n;i++) 5 { 6 T key=a[i]; 7 // insert key(namely a[i]) into the sorted sequence a[0..i-1] 8 int j=i-1; 9 while(key<a[j] && j>=0) 10 { 11 a[j+1]=a[j]; 12 j--; 13 } 14 a[j+1]=key; 15 } 16 }
3. 算法分析排序
3.1 算法可行性(循環不變式):內存
初始條件:在算法開始時,將要排序的表分割成A[0]和A[1..n-1].而左邊的表A[0]爲已排序的表,A[0]中只包含一個元素,顯然成立,右邊A[1..n-1] 爲未排序的表。模板
保持:在兩層循環中,目的是將元素A[i]插入到A[0..i-1]的正確位置中。它將從A[j-1]開始依次與已排序中的元素進行比較,直至找到一個位置k使得A[j-1]>=A[k]或者已經找到已排序的表頭爲止。而後將該元素插入到該位置。而後將i+1,開始下一次的插入。class
終止:在內層循環中,當A[i]插入到已排序的表中終止內層循環。在外層循環中,當因此未排序的表的元素都插入到已排序的表中,即i=n時,算法終止。終止時,已排序的表長爲n,未排序的表長爲0,代表已將A[0..n-1]排完序。基礎
3.2 時間複雜度
最壞狀況:O(n^2);
最好狀況:O(n)。
當輸入的待排序的序列已經排好序,則只須要進行n-1比較就能夠完成排序。故最好的狀況下,算法的複雜度爲O(n)。當輸入的待排序的序列爲徹底逆序,即由大到小排列時,須要進行1+2+3+...+n-1=0.5n(n-1)次比較才能夠完成排序。故最壞狀況下,算法複雜度爲O(n^2)。其餘狀況介於這兩種狀況之間。
3.3 空間複雜度
插入排序是在原數組的基礎上進行的排序,咱們稱之爲原地排序(即只有常數個元素被存放到數組之外的空間中去)。可見插入排序對內存的使用率仍是很高的,不會白白浪費內存空間。因此它的空間複雜度爲O(n).
3.4 利用機率論知識分析插入排序算法
待續。。。