標籤:
1 .插入排序的過程如同我們平時打撲克牌取牌插入的過程,不斷將取出的撲克牌插入已經排好的地方。
插入排序過程初始有序區間大小為1,取出無序區間的首元素,尋找有序區間的合適位置,進行插入。不斷重複上述過程,即可完成操作。
圖解樣本
1 //插入排序 2 //karllen @2015 3 void insertSort() 4 { 5 int i ,j ,temp; 6 for(i = 1;i<n;++i) //從第二個元素開始插入 7 { 8 temp = a[i]; //a[i]會被覆蓋,臨時儲存 9 j = i - 1;10 while(j>=0&&a[j]>temp) //邊移動邊比較11 {12 a[j+1] = a[j];13 }14 a[j+1] = temp;15 }16 }
2 .shell 排序演算法是插入排序演算法的一種,希爾排序先要將排序的一組資料按照某個增量分成若干組,相隔增量個的元素組成一組分別進行
插入排序,然後縮小增量,不斷重複上述過程。直到將增量減小到1時,整個要排序的結果只能分成一組,並對其進行插入排序,即可完成。
圖解樣本:
取增量組為{3,2,1};
增量為3時,分為三組{70,10,90,60},{30,80,100,45},{40,20,75}分別進行插入排序,結果為
{10,60,70,90}
{30,45,80,100}
{20,40,75}; 執行完增量為3的分組插入排序後,結果為{10,30,20,60,45,40,70,80,75,90,100}局部有序性增強。
增量為2時,{10,30,40,60,45,20,70,80,75,90,100}被分為兩組,{10,20,45,70,75,100},{30,60,40,80,90}分別進行插入排序,結果為
{10,20,45,70,75,100}
{30,40,60,80,90};執行為增量為2的分組插入排序後,結果為{10,30,20,40,45,60,70,80,75,90,100}局部有序性進一步增強。
最後執行增量為1的直接插入排序,結果為{10,20,30,40,45,60,70,75,80,90,100}至此shell排序結束。
要點:分組進行插入排序的過程目的是使資料朝著局部有序的方向發展。
這裡涉及增量的選取,增量的選取理論上應該是兩兩互素的。
代碼如下:
#include <iostream>/* run this program using the console pauser or add your own getch, system("pause") or input loop */// karllen //2015 void shellSort(int *a,int length); //希爾排序 int main(int argc, char** argv){ int a[] = {70,30,40,10,80,20,90,100,75,60,45}; shellSort(a,11); for(int i = 0;i<11;++i) { std::cout<<a[i]<<" "; } return 0;}void shellSort(int *a,int length) //希爾排序 { for(int incrt = length/2; incrt>0;incrt /= 2) { for(int i = 0;i<incrt;++i) //依次排序不同增量構成的子序列 { /*int j = i+incrt; int r; while(j<length) //普通插入排序,先比較後移動 { r = i; while(a[j]>a[r]) { r = r+incrt; } if(r!=j) { int temp = a[j]; int k = j; while(k>=r) { a[k] = a[k-incrt]; k -= incrt; } a[r] = temp; } j = j+incrt; } */ //改進後的直接插入排序,邊移動邊比較。 int j = i+incrt; int r,temp; while(j<length) { r = j-incrt; temp = a[j]; while(r>=0 && a[r]>temp) //從後往前邊移動邊比較 { a[r+incrt] = a[r]; r = r-incrt; } a[r+incrt] = temp; // 插入 j = j+incrt; // 轉入下一元素的插入過程 } } } }
測試結果:
書到用時方恨少,是非經過不知難。 博觀而約取,厚積而薄發。@karllen 每天進步一點點。
插入排序與shell排序(希爾排序)