原始地址:C / C++演算法學習筆記(6)-插入法
插入法:
插入法較為複雜,它的基本工作原理是抽出牌,在前面的牌中尋找相應的位置插入,然後繼續下一張。
#include <iostream.h>void InsertSort(int* pData,int Count){ int iTemp; int iPos; for(int i=1;i<Count;i++) { iTemp = pData[i]; iPos = i-1; while((iPos>=0) && (iTemp<pData[iPos])) { pData[iPos+1] = pData[iPos]; iPos--; } pData[iPos+1] = iTemp; }} void main(){ int data[] = {10,9,8,7,6,5,4}; InsertSort(data,7); for (int i=0;i<7;i++) cout<<data[i]<<" "; cout<<"/n";}
i=1時:
iTemp=pData[1]=9
ipos=1-1=0;
ipos=0>=0 && iTemp=9<pData[0]=10;
pData[1]=pData[0]=10;
ipos--=0-1=-1;
pData[0]=9; 9-10-8-7-6-5-4
i=2時:
iTemp=pData[2]=8
ipos=2-1=1;
ipos=1>=0 && iTemp=8<pData[1]=10;
pData[2]=pData[1]=10;
ipos--=1-1=0; 9-10-10-7-6-5-4
ipos=0>=0 && iTemp=8<pData[0]=9;
pData[1]=pData[0]=9;
ipos--=0-1=-1;
pData[0]=8; 8-9-10-7-6-5-4
i=3時:
iTemp=pData[3]=7
ipos=3-1=2;
ipos=2>=0 && iTemp=7<pData[2]=10;
pData[3]=pData[2]=10;
ipos--=2-1=1; 8-9-10-10-6-5-4
ipos=1>=0 && iTemp=8<pData[1]=9;
pData[2]=pData[1]=9;
ipos--=1-1=0; 8-9-9-10-6-5-4
ipos=0>=0 && iTemp=7<pData[0]=8;
pData[1]=pData[0]=8;
ipos--=0-1=-1;
pData[0]=7; 7-8-9-10-6-5-4
i=4時:
iTemp=pData[4]=6;
ipos=4-1=3;
ipos=3>=0 && iTemp=6<pData[3]=10;
pData[4]=pData[3]=10;
ipos--=3-1=2; 7-8-9-10-10-5-4
ipos=2>=0 && iTemp=7<pData[2]=9;
pData[3]=pData[2]=9;
ipos--=2-1=1; 7-8-9-9-10-5-4
ipos=1>=0 && iTemp=7<pData[1]=8;
pData[2]=pData[1]=8;
ipos--=1-1=0; 7-8-8-9-10-5-4
ipos=0>=0 && iTemp=7<pData[0]=7;
pData[1]=pData[0]=7;
ipos--=1-1=0;
pDate[0]=6; 6-7-8-9-10-5-4
由上述可知:
插入排序是先把集合中的下一個元素抽取出來放到一個臨時變數裡面和第一個元素比較。並記錄該元素在集合中的位置如果第二個元素比第一個小,那麼第一個元素和第二個元素對調。下一次再用第三個元素先和變化後的第二個元素比較,如果變化後的第二個元素小於第三個元素,用第二個元素的值覆蓋第三個元素。在從臨時變數裡面取出該元素放到第二個元素中去。
倒序(最糟情況)
第一輪:10,9,8,7->9,10,8,7(交換1次)(迴圈1次)
第二輪:9,10,8,7->8,9,10,7(交換1次)(迴圈2次)
第一輪:8,9,10,7->7,8,9,10(交換1次)(迴圈3次)
迴圈次數:6次
交換次數:3次
其他:
第一輪:8,10,7,9->8,10,7,9(交換0次)(迴圈1次)
第二輪:8,10,7,9->7,8,10,9(交換1次)(迴圈2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)(迴圈1次)
迴圈次數:4次
交換次數:2次
上面結尾的行為分析事實上造成了一種假象,讓我們認為這種演算法是簡單演算法中最好的,其實不是,因為其迴圈次數雖然並不固定,我們仍可以使用O方法。從上面的結果可以看出,迴圈的次數f(n)<=1/2*n*(n-1)<=1/2*n*n。所以其複雜度仍為O(n*n)(這裡說明一下,其實如果不是為了展示這些簡單排序的不同,交換次數仍然可以這樣推導)。
現在看交換,從外觀上看,交換次數是O(n)(推導類似選擇法),但我們每次要進行與內層迴圈相同次數的‘=’操作。正常的一次交換我們需要三次‘=’而這裡顯然多了一些,所以我們浪費了時間。
最終,我個人認為,在簡單排序演算法中,選擇法是最好的。
插入排序
#include <iostream>usingnamespace std; void coutstream(int a[],int n){ for(int i=0;i!=n;i++) cout<<a[i]<<" ";} void insertsort(int a[],int n){int temp; for(int i=1;i<n;i++){ int j=i; temp=a[i];//先把a[i]位置的資料存起來 while(j>0&&temp<a[j-1]) { a[j]=a[j-1]; j--; } a[j]=temp;}} int main(){ int a[5]={1,6,4,8,4}; insertsort(a,5);//插入排序 coutstream(a,5);// return0;}