本文我準備用Java實現希爾排序。具體的排序算法過程已經在註釋裏面了,大家可以複製代碼到IDE裏面,用DEBUG模式研究算法的過程(算法參考:https://baike.baidu.com/item/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F):
import java.util.Arrays;
import java.util.Random;
/**
* @author LiYang
* @ClassName ShellSort
* @Description 希爾排序算法
* @date 2019/11/5 15:22
*/
public class ShellSort {
/**
* 希爾排序算法(ShellSort)
* @param arr 待排序數組
*/
public static void shellSort(int[] arr){
//希爾排序的間隔長度
int gap = arr.length;
//一直循環,直到最後來一次插入排序
while (true) {
//希爾排序的間隔,初始爲arr.length的一半,以後
//每次都減半(這裏可以改,比如3),直到最後減到1
gap = gap / 2;
//希爾排序開始,間隔從大到小,數組越來越有序
for (int i = 0; i < gap; i++) {
//這個循環裏其實就是一個插入排序
//只不過是跨越了gap的跳躍數組的插入排序
for (int j = i + gap; j < arr.length; j = j + gap) {
//準備向左插入的元素
int insert = arr[j];
//移動插入元素的左邊的用於比較的元素
int left = j - gap;
/*
* 較小元素向左的插入排序,直到遇到比自己小的,或者到左邊界了
* 本例的插入排序,就是一直跟左邊的比,遇到大的就被其左邊的賦值,
* 然後自己又往左走一個gap繼續……直到走不動了,就賦值自己
*/
//如果左邊比較的元素未到左邊界,且左邊的數字大於移動插入的元素
while (left >= 0 && arr[left] > insert) {
//將左邊大的挪到右邊
arr[left + gap] = arr[left];
//左邊比較的元素再往左移動一個gap,進行下一次比較
left = left - gap;
}
//最後,用於比較的left的右邊一個gap即爲插入的終點
arr[left + gap] = insert;
}
}
//如果間隔已經爲1了,就相當於已經來過一次插入排序了
//數組必然有序了,希爾排序結束,break
if (gap == 1){
break;
}
}
}
/**
* 驗證希爾排序算法
* @param args
*/
public static void main(String[] args){
//待排序數組
int[] arr = new int[30];
//隨機數類
Random random = new Random();
//隨機生成排序數組(100以內的整數)
for (int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(100);
}
//打印待排序數組
System.out.println("希爾排序前:" + Arrays.toString(arr));
//進行希爾排序
shellSort(arr);
//打印希爾排序後的數組
System.out.println("希爾排序後:" +Arrays.toString(arr));
}
}
運行 ShellSort 類的main方法,希爾排序算法測試通過:
希爾排序前:[66, 96, 68, 19, 52, 24, 75, 31, 71, 1, 89, 29, 37, 43, 26, 20, 48, 83, 68, 39, 61, 74, 83, 3, 57, 19, 96, 51, 38, 32]
希爾排序後:[1, 3, 19, 19, 20, 24, 26, 29, 31, 32, 37, 38, 39, 43, 48, 51, 52, 57, 61, 66, 68, 68, 71, 74, 75, 83, 83, 89, 96, 96]