Java實現希爾排序

  希爾排序(Shell Sort)是插入排序的一種,是針對直接插入排序算法的改進,是將整個無序列分割成若干小的子序列分別進行插入排序,希爾排序並不穩定。該方法又稱縮小增量排序,因DL.Shell於1959年提出而得名。java

1、基本思想算法

  先取一個小於n的整數d1做爲第一個增量,把文件的所有記錄分紅d1個組。全部距離爲d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;而後,取第二個增量d2<d1重複上述的分組和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即全部記錄放在同一組中進行直接插入排序爲止。shell

2、下面讓咱們看一下希爾排序的一個實例:數組

3、希爾排序的時間性能優於直接插入排序的緣由:
     ①當文件初態基本有序時直接插入排序所需的比較和移動次數均較少。
     ②當n值較小時,n和n2的差異也較小,即直接插入排序的最好時間複雜度O(n)和最壞時間複雜度0(n2)差異不大。
     ③在希爾排序開始時增量較大,分組較多,每組的記錄數目少,故各組內直接插入較快,後來增量di逐漸縮小,分組數逐漸減小,而各組的記錄數目逐漸增多,但因爲已經按di-1做爲距離排過序,使文件較接近於有序狀態,因此新的一趟排序過程也較快。
        所以,希爾排序在效率上較直接插人排序有較大的改進。
       性能

增量序列的選擇:Shell排序的執行時間依賴於增量序列。好的增量序列的共同特徵(查到的資料都這麼講): spa

     ① 最後一個增量必須爲1;
     ② 應該儘可能避免序列中的值(尤爲是相鄰的值)互爲倍數的狀況。 
     blog

4、具體的java代碼實現排序

 

public static void shellSort(int[] a){
		double gap = a.length;//增量長度
		int dk,sentinel,k;
		while(true){
			gap = (int)Math.ceil(gap/2);//逐漸減少增量長度
			dk = (int)gap;//肯定增量長度 
			for(int i=0;i<dk;i++){
				//用增量將序列分割,分別進行直接插入排序。隨着增量變小爲1,最後總體進行直接插入排序
				for(int j=i+dk;j<a.length;j = j+dk){
					k = j-dk;
					sentinel = a[j];
					while(k>=0 && sentinel<a[k]){
						a[k+dk] = a[k];
						k = k-dk;
					}
					a[k+dk] = sentinel;
				}
			}
			//當dk爲1的時候,總體進行直接插入排序  
			if(dk==1){
				break;
			}
		}
	}

 

5、算法分析ci

希爾排序的算法性能

排序類別table

排序方法

時間複雜度

空間複雜度

穩定性

複雜性

平均狀況

最壞狀況

最好狀況

插入排序

希爾排序

O(Nlog2N)

O(N1.5)

 

O(1)

不穩定

較複雜

時間複雜度

步長的選擇是希爾排序的重要部分。只要最終步長爲1任何步長序列均可以工做。

算法最開始以必定的步長進行排序。而後會繼續以必定步長進行排序,最終算法以步長爲1進行排序。當步長爲1時,算法變爲插入排序,這就保證了數據必定會被排序。
Donald Shell 最初建議步長選擇爲N/2而且對步長取半直到步長達到1。雖然這樣取能夠比O(N2)類的算法(插入排序)更好,但這樣仍然有減小平均時間和最差時間的餘地。可能希爾排序最重要的地方在於當用較小步長排序後,之前用的較大步長仍然是有序的。好比,若是一個數列以步長5進行了排序而後再以步長3進行排序,那麼該數列不只是以步長3有序,並且是以步長5有序。若是不是這樣,那麼算法在迭代過程當中會打亂之前的順序,那就

不會以如此短的時間完成排序了。

已知的最好步長序列是由Sedgewick提出的(1, 5, 19, 41, 109,...),該序列的項來自這兩個算式。

這項研究也代表「比較在希爾排序中是最主要的操做,而不是交換。」用這樣步長序列的希爾排序比插入排序和堆排序都要快,甚至在小數組中比快速排序還快,可是在涉及大量數據時希爾排序仍是比快速排序慢。

 算法穩定性

由上文的希爾排序算法演示圖便可知,希爾排序中相等數據可能會交換位置,因此希爾排序是不穩定的算法。

6、問題

希爾排序必定正確麼?換句話說如何選取增量序列才能保證正確(包括長度、值)?是的,最後一次只要保證增量是1就ok(無論序列長度,只不過效率就低了),如果序列只有1,那就是直接插入排序了,不知道對否。

7、下面給你們列出8種排序之間的關係:

 

相關文章
相關標籤/搜索