插入排序——希爾排序

希爾排序

算法思想:
希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨着增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。本質是分組插入排序,每次將較小的元素插入到前面,較大的元素留在後面。

排序過程如下:
以26、53、67、48、57、13、48、32、60、50爲例,
1、第一趟排序以n/2即10/2=5爲間隔
26536748、57、13483260、50,同一顏色爲一組,同一組內進行直接插入排序,改變的位置也只能是組內元素原有的位置,結果爲13 48 32 48 50 26 53 67 50 57。
2.第二趟以5/2=2爲間隔
13 4832 48 50 2653 67 50 57,結果爲13 26 32 48 50 48 57 60 67
3.第三趟以1爲間隔,即直接插入排序。
結果爲 13 26 32 48 48 50 57 60 67

java實

public static void shellSort(int a[]) {
		int i,j;
		int gap;//記錄間隔
		int len=a.length;
		for(gap=len/2;gap>0;gap/=2) {
			for(i=gap;i<len;i++) {//初始從第gap元素開始
				if(a[i]<a[i-gap]) {//a[i-gap]<a[i]時,表示間隔數組內a[i]之前的元素有序,a[i]<a[i-gap]則講元素一邊向後移一邊搜索
					int temp=a[i];
					for(j=i-gap;j>=0&&a[j]>temp;j-=gap) {
						a[j+gap]=a[j];
					}
					a[j+gap]=temp;
				}
			}
		}
	}
	
	public static void shellSort2(int a[]) {
		int i,j,gap;
		int len=a.length;
		for(gap=len/2;gap>0;gap/=2) {
			for(i=gap;i<len;i++) { //初始從gap開始
				for(j=i-gap;j>=0&&a[j+gap]<a[j];j-=gap) {//用元素交換替換上面方法的元素後移
					int temp=a[j+1];
					a[j+1]=a[j];
					a[j]=temp;
				}
			}
		}
	}


算法分析:
1、增量選擇
    shell排序時間依賴與增量序列,好的增量應該避免序列中的值互爲倍數的情況;最後一個增量必須爲1;
2、時間複雜度:
有人通過大量的實驗,給出了較好的結果:當n較大時,比較和移動的次數約在n^l.25到1.6n^1.25之間。

希爾排序的時間複雜度與增量(即,步長gap)的選取有關。例如,當增量爲1時,希爾排序退化成了直接插入排序,此時的時間複雜度爲O(N²),而Hibbard增量的希爾排序的時間複雜度爲O(n^3/2)。

希爾排序時間複雜度的下界是n*log2n。希爾排序沒有快速排序算法快 O(n(logn)),因此中等大小規模表現良好,對規模非常大的數據排序不是最優選擇

3.時間性能優於直接插入排序,,希爾排序的時間性能優於直接插入排序的原因:

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

因此,希爾排序在效率上較直接插入排序有較大的改進。

4.不穩定的排序



發佈了34 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章