希爾排序算法的訓練和思考

希爾排序(最小增量排序)


基本思想:算法先將要排序的一組數按某個增量d(n/2,n爲要排序數的個數)分成若干組,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。當增量減到1時,進行直接插入排序後,排序完成。


下面是關於算法的實現


public class ShellSort {
	//希爾排序
	public static void main(String[] args) {
		 int a[] = {5, 54, 6, 3, 78, 34, 12, 45, 56, 100};  
		 double d1 = a.length;
		 int temp = 0;
		 
		 while(true){
			 d1 = Math.ceil(d1/2); //ceil方法向下取整
			 int d = (int)d1; //獲得增量
			 for(int x = 0; x < d; x++) { //x作爲每一組的起始下標
				 
				 for (int i = x + d; i < a.length; i += d) {
					 int j = i - d;
					 temp = a[i]; //a[i]是要插入的數
					 for(; j >= 0 && a[j] > temp ; j-=d) {
						 a[j+d] = a[j];
					 }
					 a[j+d] = temp;
				 } 
			 }
			 if(d == 1) {
				 break;
			 }
		 } 
		 
		 for (int i = 0; i < a.length; i++ ) {
			 System.out.print(a[i]+" ");
		 }

	}

}




希爾排序和直接插入排序算法其實特別相象,因爲是相當於通過增量的變化將原數組變成多組的的直接插入排序,在最後一次直接插入排序的時候,數組已經基本有序。


在實現的過程中出現兩個問題:

1、第17行  for(; j >= 0 && a[j] > temp ; j-=d) 這一句一開始被我寫成了 for(; j > 0 && a[j] > temp ; j-=d),出現的結果就是數組第一位數字不會被拿去比較,因爲直接短路的問題,後面循環體本次並不會執行。


2、發現可以有另一種實現方法。(區別主要在第17行到第21行),測試結果並無問題。

public class ShellSort2 {
	//希爾排序
	public static void main(String[] args) {
		 int a[] = {5, 54, 6, 3, 78, 34, 12, 45, 56, 100};  
		 double d1 = a.length;
		 int temp = 0;
		 
		 while(true){
			 d1 = Math.ceil(d1/2); //ceil方法向下取整
			 int d = (int)d1; //獲得增量
			 for(int x = 0; x < d; x++) { //x作爲每一組的起始下標
				 
				 for (int i = x + d; i < a.length; i += d) {
					 int j = i - d;
					 temp = a[i]; //a[i]是要插入的數
					 for(; j >= 0 && a[j] > temp ; j-=d) {
						 a[j+d] = a[j];
						 a[j] = temp;
					 }
				 } 
			 }
			 if(d == 1) {
				 break;
			 }
		 } 
		 
		 for (int i = 0; i < a.length; i++ ) {
			 System.out.print(a[i]+" ");
		 }

	}

}


總的來說實現過程就是:1、定義增量

2、通過增量進行分組

3、對分好的組進行直接插入排序

4、改變增量值直到增量爲1時,進行直接插入排序。



時間複雜度:

希爾排序是按照不同步長對元素進行直接插入排序,當剛開始元素很無序的時候,步長最大,所以插入排序的元素個數很少,排序速度快;下一趟,步長變小,但是元素排列已經比之前相對有序了,而插入排序對於有序的序列效率很高,所以希爾排序的的時間複雜度會比直接插入排序的複雜度好一些。(以下時間複雜度是本人上網查詢的結果)

①平均時間複雜度是 O(n^1.3)

②最優時間複雜度是 O(n)

③最壞時間複雜度是 O(n^2)


空間複雜度:和直接插入排序一樣,只需要一個輔助存儲空間,所以空間複雜度爲O(1)


穩定性:希爾排序在增量不同時的分組排序,可能會導致相同的數的相對位置發生改變,是不穩定的。


適用情況:希爾排序的比較次數和移動次數都比直接插入排序要少,最壞情況下的比較次數是(n^1.5),n越大時,效果越明顯,所以適合初始記錄無序,n較大的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章