各種插入排序演算法小結
巧若拙直接插入排序是將元素vec[i]插入到有序序列vec[0..i-1], 依次將vec[i]與vec[i-1],vec[i-2],...進行比較,找到插入位置即將vec[i]插入,原來位置上的物件向後順移。
直接插入演算法**如下:
voidinsertsort_1(int vec, int n) //直接插入排序
int i, j;
int temp;
for (i=1; itemp= vec[i];
for(j=i;(j>0) && (vec[j-1]>temp); j--)
vec[j]= vec[j-1];
vec[j]= temp;
直接插入法在查詢插入位置時採取逐一比較的方法,效率較低,為了提高查詢效率,可採用折半查詢法。**如下:
voidinsertsort_2(int vec, int n) //折半插入排序
int i, j, low, high, mid;
int temp;
for (i=1; itemp= vec[i];
low= 0;
high= i-1;
while(low <= high) //折半查詢插入位置
mid= (low + high)/2;
if(vec[mid] > temp)
high= mid -1;
else
low= mid + 1;
//進行插入操作
for(j=i; j>low; j--)
vec[j]= vec[j-1];
vec[low]= temp;
插入排序在對幾乎已經排好序的資料操作時,效率高,幾乎可以達到線性排序的效率,但進行插入操作時,每次只能將資料移動一位,難免出現大量重複移動,如果能將元素盡可能快的移動到它「該去」的地方,將大大減少重複移動的次數,提高效率。
希爾排序是把全部元素分組排序,將所有距離為步長gap的元素放在同乙個組中,通過「跳躍式移動」的方法,能讓元素每次移動一大步,即步長gap>1,大大提高了移動的效率。一趟排序下來,雖然同組的元素沒有挨在一起,各組元素相互隔開,但是由於每一組都已經各自排好序了,所以整個序列還是「基本有序」的。
然後再取越來越小的步長進行排序,直到步長gap=1時,就是普通的插入排序,但是到了這步,整個序列是「基本有序」了,直接插入排序也能高效完成。
**如下:
voidshellsort(int vec, int n) //希爾排序
int i, j, gap;
int temp;
for (gap=n/2; gap>0; gap/=2)
for(i=gap; itemp= vec[i];
for(j=i; (j>=gap) && (tempvec[j]= vec[j-gap];
vec[j]= temp;
希爾排序的關鍵在於不能將元素隨便分組後各自排序,而是將相隔一定步長的元素組成乙個子串行,實現跳躍式的移動,使得排序的效率提高。
步長的選擇是希爾排序的重要部分。只要最終步長為1任何步長序列都可以工作。演算法最開始以一定的步長進行排序。然後會繼續以一定步長進行排序,最終演算法以步長為1進行排序。當步長為1時,演算法變為插入排序,這就保證了資料一定會被排序。
donald shell 最初建議步長選擇為n/2,並且對步長取半直到步長達到 1。雖然這樣取可以比o(n2)類的演算法(插入排序)更好,但這樣仍然有減少平均時間和最差時間的餘地。可能希爾排序最重要的地方在於當用較小步長排序後,以前用的較大步長仍然是有序的。比如,如果乙個數列以步長5進行了排序然後再以步長3進行排序,那麼該數列不僅是以步長3有序,而且是以步長5有序。如果不是這樣,那麼演算法在迭代過程中會打亂以前的順序,那就不會以如此短的時間完成排序了。
已知的最好步長序列是由sedgewick提出的 (1, 5, 19, 41, 109,...),該序列的項來自 9 * 4^i - 9 * 2^i + 1 和 4^i - 3 * 2^i + 1 這兩個算式。這項研究也表明"比較在希爾排序中是最主要的操作,而不是交換。"用這樣步長序列的希爾排序比插入排序和堆排序都要快,甚至在小陣列中比快速排序還快,但是在涉及大量資料時希爾排序還是比快速排序慢。
另乙個在大陣列中表現優異的步長序列是(斐波那契數列除去0和1將剩餘的數以**分割槽比的兩倍的冪進行運算得到的數列):(1, 9, 34,182, 836, 4025, 19001, 90358, 428481, 2034035, 9651787, 45806244, 217378076,1031612713, …)。
排序小結 2 插入排序
插入排序 插入排序 insertion sort 的基本思想是 每次將乙個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子檔案中的適當位置,直到全部記錄插入完成為止。本節介紹兩種插入排序方法 直接插入排序和希爾排序。直接插入排序基本思想 1 基本思想 假設待排序的記錄存放在陣列r 1.n 中。初...
插入排序演算法
插入排序演算法 思想 把排序過程看作是序列單個有序擴充套件為整體有序的過程,即首先取序列第二個元素與第乙個元素比較,將其插入合適位置,再將第三個元素與前兩個元素比較,將其插入合適位置,如此進行,直到最後取第n個元素與前n 1個元素進行比較並將其插入合適位置。演算法 建立日期 2004 12 14 插...
演算法 插入排序
include include 插入排序 n 2為的效率。具體思想 將陣列分為兩部分,一部分是有序的,一部分為無序的 然後從無序中選取乙個數插入在有序的數中的恰當的位置,以此迭代,直到無序的數全部遍厲完畢 void insert sort int a,int n a j tmp break retu...