1.介紹
希爾排序是希爾(Donald Shell)於1959年提出的一種排序演算法。希爾排序也是一種插入排序,它是簡單插入排序經過改進之後的一個更高效的版本,也稱為縮小增量排序。
2.基本思想
希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序演算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個檔案恰被分成一組,演算法便終止
3.示意圖
4.程式碼
using System; namespace DataStructure { public class ShellSort { /// <summary> /// 測試希爾排序 /// </summary> public static void Test() { int[] arr = { 8, 9, 1, 7, 2, 3, 5, 4, 6, 0 }; Console.WriteLine("需要排序的陣列:" + ArrayToString(arr)); Console.WriteLine("\n封裝後的測試"); //測試封裝後的希爾排序 Sort(arr); Console.WriteLine("\n封裝前的測試"); arr = new int[] { 8, 9, 1, 7, 2, 3, 5, 4, 6, 0 }; int temp = 0; //希爾排序第一輪 //因為第一輪排序,是將十個資料分成了五組 for (int i = 5; i < arr.Length; i++) { //遍歷各組中所有元素(10/2=5)步長五 for (int j = i - 5; j >= 0; j -= 5) { if (arr[j] > arr[j + 5]) { temp = arr[j]; arr[j] = arr[j + 5]; arr[j + 5] = temp; } } } Console.WriteLine("\n第一輪希爾排序的結果:" + ArrayToString(arr)); //3,5,1,6,0,8,9,4,7,2 //希爾排序第二輪 //因為第二輪排序,是將十個資料分成了5/2=2組 for (int i = 2; i < arr.Length; i++) { for (int j = i - 2; j >= 0; j -= 2) { if (arr[j] > arr[j + 2]) { temp = arr[j]; arr[j] = arr[j + 2]; arr[j + 2] = temp; } } } Console.WriteLine("\n第二輪希爾排序的結果:" + ArrayToString(arr)); //希爾排序第三輪 //因為第三輪排序,是將十個資料分成了2/2=1組 for (int i = 1; i < arr.Length; i++) { for (int j = i - 1; j >= 0; j -= 1) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } Console.WriteLine("\n第三輪希爾排序的結果:" + ArrayToString(arr)); } /// <summary> /// 封裝希爾排序 /// </summary> /// <param name="arr"></param> private static void Sort(int[] arr) { int temp = 0; int count = 0; //遍歷各組中的所有元素(共gap組,每組有個元素),步長gap for (int gap = arr.Length / 2; gap > 0; gap /= 2) { for (int i = gap; i < arr.Length; i++) { for (int j = i - gap; j >= 0; j -= gap) { //如果當前元素大於加上步長後的那個元素,說明交換 if (arr[j] > arr[j + gap]) { temp = arr[j]; arr[j] = arr[j + gap]; arr[j + gap] = temp; } } } Console.WriteLine($"\n第{++count }輪希爾排序的結果:{ArrayToString(arr)}"); } } private static string ArrayToString(int[] arr) { return string.Join(",", arr); } } }
5.演示結果