希爾排序的理解和實現(Java)


希爾排序原理

希爾排序(shell sort)這個排序方法又稱為縮小增量排序,是1959年D·L·Shell提出來的。
該方法的基本思想是:設待排序元素序列有n個元素,首先取一個整數increment(小於n)作為間隔將全部元素分為increment個子序列,所有距離為increment的元素放在同一個子序列中,在每一個子序列中分別實行直接插入排序。然后縮小間隔increment,重復上述子序列划分和排序工作。直到最后取increment=1,將所有元素放在同一個子序列中排序為止。
由於開始時,increment的取值較大,每個子序列中的元素較少,排序速度較快,到排序后期increment取值逐漸變小,子序列中元素個數逐漸增多,但由於前面工作的基礎,大多數元素已經基本有序,所以排序速度仍然很快。

希爾排序流程

1、給出一個待排序的數據列:
在這里插入圖片描述2、第一趟取increment的方法是:n/3向下取整+1=3(關於increment的取法之后會有介紹)。將整個數據列划分為間隔為3的3個子序列,然后對每一個子序列執行直接插入排序,相當於對整個序列執行了部分排序調整。圖解如下:
在這里插入圖片描述3、第二趟將間隔increment= increment/3向下取整+1=2,將整個元素序列划分為2個間隔為2的子序列,分別進行排序。圖解如下:
在這里插入圖片描述
4、第3趟把間隔縮小為increment= increment/3向下取整+1=1,當增量為1的時候,實際上就是把整個數列作為一個子序列進行插入排序,圖解如下:
在這里插入圖片描述
5、直到increment=1時,就是對整個數列做最后一次調整,因為前面的序列調整已經使得整個序列部分有序,所以最后一次調整也變得十分輕松,這也是希爾排序性能優越的體現。

希爾排序實現代碼:

public class ShellSort {

	public void shellSort(int[] elem) {
		int i, j;
		int increment = elem.length;
		
		do {
			increment = increment / 3 + 1;
			for (i = increment + 1; i < elem.length; i++) {
				if(elem[i] < elem[i - increment]) {
					elem[0] = elem[i];
					for (j = i - increment; j > 0 && elem[0] < elem[j]; j -= increment) {
						elem[j + increment] = elem[j];
					}
					elem[j + increment] = elem[0];
				}
			}
		} while(increment > 1);
	}
	
	public static void main(String[] args) {
		int[] elem = {0, 9, 1, 5, 8, 3, 7, 4, 6, 2};
		ShellSort s = new ShellSort();
		s.shellSort(elem);
		for (int i = 1; i < elem.length; i++) {
			System.out.print(elem[i] + ", ");
		}
		
	}
}
增量increment的取法

增量increment的取法有各種方案。最初shell提出取increment=n/2向下取整,increment=increment/2向下取整,直到increment=1。但由於直到最后一步,在奇數位置的元素才會與偶數位置的元素進行比較,這樣使用這個序列的效率會很低。后來Knuth提出取increment=n/3向下取整+1.還有人提出都取奇數為好,也有人提出increment互質為好。應用不同的序列會使希爾排序算法的性能有很大的差異。

希爾排序復雜度分析

對於希爾排序其增量increment的選擇非常關鍵,最燃至今其怎樣選擇還是一個數學難題,但是通過大量研究表明,當增量序列為dlta[k]= 2 t k + 1 2^{t-k+1} -1(0≤k≤t≤ l o g 2 log_2 (n+1))時,可以獲得不錯的效率,其時間復雜度為O( n 3 / 2 n^{3/2} ),要好於直接排序的O( n 2 n^2 ),需要注意的是增量序列的最后一個增量值必須等於1才行。另外由於記錄是跳躍性的移動,希爾排序並不是一種穩定的排序算法。


本文參考https://blog.csdn.net/weixin_37818081/article/details/79202115


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM