插入排序適合資料量較小或者部分有序的序列排序,但是當序列的最小值在最右端時,需要比較n-1次並且移動n-1次才能將最小數插入序列的最左端。希爾排序對直接插入排序做了改進。在插入排序的基礎上,將序列分組,利用了插入排序對資料量較小和部分有序序列高效的性質。
希爾排序首先將序列以「增量」h分成h組,分組情況如圖
在組內進行插入排序。一次排序完成後,減小「增量」h,繼續分組,在組內進行插入排序,直到h=0為止。
希爾排序利用了插入排序的性質,開始時h較大,每組的資料量較小,之後h較小,序列部分有序。
這裡還有乙個問題,如何選擇增量h呢?一般h小於序列長度,按照規則h=
3h+1
,即h=
1,4,
13,40,
121,
364,..
. ,從小於序列長度的數字開始,依次減小。
shellsort(a)
//求增量h
while h3
h=h*3+1
//對每個h分組進行插入排序,直到h==0
while h>=1
//將每組序列插入排序
for i=h to a.length-1
//將a[i]插入到a[i-h],a[i-2h]...中
for j=i;j>=h && a[j]1])
//減小增量h
h=h/3;
public
class method ;
shellsort(array);
for(int x:array)
}public
static
void
shellsort(int a)
}//減小增量h
h /= 3;}}
}
時間複雜度:
最好情況:o(n)
最壞情況:o(n^2)
平均情況:o(n^1.3)
空間複雜度:o(1),原址排序
1、希爾排序的效能優於插入排序,對於大型陣列表現也很好;
2、演算法的效能不穩定,效能不僅取決於增量序列,還取決與增量序列之間的數學性質等;
3、選擇好的增量序列有助於提高演算法的效能,一般使用上文介紹的。
4、希爾排序每次迴圈之後,不能確定乙個元素的最終位置。
5、對插入排序的改進還有折半插入排序,每次將a[i]插入到a[0]到a[i-1]中時,利用前面i-1個數有序的性質,進行二分查詢a[i]應該插入的位置。由於折半插入排序比較次數減少,但是元素移動次數沒有變,所以時間複雜的和直接插入排序一樣。
學習排序演算法4 希爾排序
此 需要用到我前面三個部落格的部分 因為此處將希爾排序和選擇排序,插入排序進行了執行時間的比較 希爾排序 思想 是一種對插入排序的改進,因為插入排序每次交換只能交換相鄰的元素,元素挪到自己正確的位置可能需要移動很多次。所以希爾排序交換不相鄰的元素,以對陣列進行區域性排序,並最終用插入排序將區域性有序...
排序演算法之(4) 希爾排序
希爾排序 shell sort 是d.l.shell於1959年提出來的一種排序演算法,在這之前排序演算法的時間複雜度基本都是o n2 o n 2 的,希爾排序演算法是突破這個時間複雜度的第一批演算法之一。我們前一節講的直接插入排序,應該說,它的效率在某些時候是很高的,比如,我們的記錄本身就是基本有...
排序演算法4 希爾排序(shell sort)
希爾排序是插入排序的優化版本,實現原理 將未知數組分為以gap為間隔的n個序列 gap的初值通常取需要排序數列的長度,每次排序之後取 gap 3 1 然後將這n個序列中的數進行比較,例如先對比序列1和序列2中的第乙個數字,若序列2中的第乙個小於學列1中的第乙個則更換兩個數的位置,然後比較序列2和序列...