1. 程式人生 > 實用技巧 >C#資料結構與算法系列(二十一):希爾排序演演算法(ShellSort)

C#資料結構與算法系列(二十一):希爾排序演演算法(ShellSort)

1.介紹

希爾排序是希爾(Donald Shell)於1959年提出的一種排序演演算法。希爾排序也是一種插入排序,它是簡單插入排序經過改進之後的一個更高效的版本,也稱為縮小增量排序。

2.基本思想

希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序演演算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個檔案恰被分成一組,演演算法便終止

3.示意圖

4.程式碼

using System;

namespace DataStructure
{
public class ShellSort
{
/// <summary>
/// 測試希爾排序
/// </summary>
public static void Test()
{
int[] arr = { , , , , , , , , , }; Console.WriteLine("需要排序的陣列:" + ArrayToString(arr)); Console.WriteLine("\n封裝後的測試"); //測試封裝後的希爾排序
Sort(arr); Console.WriteLine("\n封裝前的測試"); arr = new int[] { , , , , , , , , , }; int temp = ;
//希爾排序第一輪
//因為第一輪排序,是將十個資料分成了五組
for (int i = ; i < arr.Length; i++)
{
//遍歷各組中所有元素(10/2=5)步長五
for (int j = i - ; j >= ; j -= )
{
if (arr[j] > arr[j + ])
{
temp = arr[j]; arr[j] = arr[j + ]; arr[j + ] = temp;
}
}
} Console.WriteLine("\n第一輪希爾排序的結果:" + ArrayToString(arr)); //3,5,1,6,0,8,9,4,7,2 //希爾排序第二輪
//因為第二輪排序,是將十個資料分成了5/2=2組
for (int i = ; i < arr.Length; i++)
{
for (int j = i - ; j >= ; j -= )
{
if (arr[j] > arr[j + ])
{
temp = arr[j]; arr[j] = arr[j + ]; arr[j + ] = temp;
}
}
} Console.WriteLine("\n第二輪希爾排序的結果:" + ArrayToString(arr)); //希爾排序第三輪
//因為第三輪排序,是將十個資料分成了2/2=1組
for (int i = ; i < arr.Length; i++)
{
for (int j = i - ; j >= ; j -= )
{
if (arr[j] > arr[j + ])
{
temp = arr[j]; arr[j] = arr[j + ]; arr[j + ] = temp;
}
}
} Console.WriteLine("\n第三輪希爾排序的結果:" + ArrayToString(arr));
} /// <summary>
/// 封裝希爾排序
/// </summary>
/// <param name="arr"></param>
private static void Sort(int[] arr)
{
int temp = ; int count = ;
//遍歷各組中的所有元素(共gap組,每組有個元素),步長gap
for (int gap = arr.Length / ; gap > ; gap /= )
{
for (int i = gap; i < arr.Length; i++)
{
for (int j = i - gap; j >= ; 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.演示結果