希尔排序是插入排序的一种,又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。
活动地址:CSDN21天学习挑战赛
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
①插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
②插入排序一般是低效的,因为插入排序每次只能移动一位数据。
基本思想:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2=1(dt,dt-1...)
该方法实质上是一种分组插入方法
一般的初次取序列的一半为增量,以后每次减半,直到增量为1。
排序过程:
先取一个正整数d1数组元素放一组,组内进行直接插入排序;然后取d2...
例如:
(以上图片来自网络)
共十个数据,取第一个增量为5,第二个为减半后的2,第三个为1,即结束排序。
与插入排序不同的是,希尔排序每次排序都更加接近有序,但是并未产生有序区,直到最后增量为1时结束排序,整个数组为有序的。
伪代码:
d = A.length / 2
while d > 0
for i = 1 to d
for j = i + d to A.length by d
tmp = A[j]
k = j - d
while k > 0 and A[k] > tmp
A[k + d] = A[k]
k = k - d
A[k + d] = tmp
d = d / 2
Java实现:
a[10] = {11,34,20,10,12,35,41,32,43,14}
public class ShellSort {
public static void main(String[] args) {
// input data
int[] a = {11,34,20,10,12,35,41,32,43,14};
// 初始化增量
int d = a.length / 2;
// 控制每一次的分组排序
while (d > 0){
// 控制每一组内的直接插入排序
for (int i = 0;i < d;i++){
// 组内进行直接插入排序
for (int j = i + d;j < a.length;j+=d){
int tmp = a[j];
int k = j - d;
while(k > 0 && a[k] > tmp){
a[k + d] = a[k];
k = k -d;
}
a[k + d] = tmp;
}
}
// 增量按一定规律每次变化
d = d / 2;
}
// 查看排序结果
for (int data : a){
System.out.print(data + "\t");
}
}
}