希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法
插入排序对于大规模的乱序数组的时候效率是比较慢的,因为它每次只能将数据移动一位,希尔排序为了加快插入的速度,让数据移动的时候可以实现跳跃移动,节省了一部分的时间开支。跳跃的间隔是变化的,最初可以选择这个数组长度的一半,接下来就是上一次跳跃间隔的一半。可以发现,当间隔为1时,就是普通的插入排序法
利用一下图片进行说明:
数据被分为gap组。需要对gap组数据进行排序。对于同一组数据,相邻两元素之间的位置相差gap。
注意:每次排序都是将数据分组,排序的时候,不是一组排完再排下一组,而是轮流进行排序。
下面来展示代码:
代码
python代码
def shellSort(listArr:list):
n=len(listArr) #列表长度
gap=int(n/2)
while gap>0:
for i in range(gap,n):
j=i
while j>=gap and listArr[j-gap]>listArr[j]: #对每一个分组,前一个元素大于后一个元素,交换
listArr[j-gap],listArr[j]=listArr[j],listArr[j-gap]
j-=gap #指针变化。每组元素中的相邻元素的位置相差gap
gap=int(gap/2) #每一轮排完,跟新gap值
return listArr
C#代码实现
namespace ShellSort
{
class Program
{
static void Main(string[] args)
{
int[] Arr = new int[] {8,9,1,7,2,3,5,4,6,0 };
int[] newArr = shellSort(Arr);
foreach (int item in newArr)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
public static int[] shellSort(int[] arr)
{
if (arr == null || arr.Length < 2) return arr;
int n = arr.Length;
// 对每组间隔为 h的分组进行排序,刚开始 h = n / 2;
for (int h = n / 2; h > 0; h /= 2)
{
//对各个局部分组进行插入排序
for (int i = h; i < n; i++)
{
// 将arr[i] 插入到所在分组的正确位置上
insertI(arr, h, i);
}
}
return arr;
}
/**
* 将arr[i]插入到所在分组的正确位置上
* arr[i]] 所在的分组为 ... arr[i-2*h],arr[i-h], arr[i+h] ...
*/
private static void insertI(int[] arr, int h, int i)
{
int temp = arr[i];
int k;
for (k = i - h; k >= 0 && temp < arr[k]; k -= h)
{
int val = arr[k + h];
arr[k + h] = arr[k];
arr[k] = val;
}
}
}
}