原理
其工作原理是定义一个间隔序列来表示排序过程中进行比较的元素之间有多远的间隔,每次将具有相同间隔的数分为一组,进行插入排序,大部分场景中,间隔是可以提前定义好的,也可以动态生成。
实现
/*
* 希尔插入,设置增量z,比较a[i]>a[i-z],进行交换
* 增量/2 一直到增量为1
* 适合大数据量的快速排序,性能良好
*/
public class 希尔插入 {
public void xier(int [] a,int z) {
int len=a.length;
int temp=-1;
int n=0;
while(z>0)
{
int i=z;//该序列a的第二个值,无序序列的第一个值
for(;i<len;i++)
{
temp=a[i];
int j=i-z;//无序序列的前一个值,为有序序列的最后一个值
while((j>=0)&&a[j]>temp)
{
a[j+z]=a[j];
j=j-z;
}
a[j+z]=temp;
}
n++;
System.out.println("第"+n+"次希尔排序 z="+z);
z=z/2;
for (int k : a) {
System.out.print(k+" ");
}
System.out.println();
}
}
public static void main(String[] args) {
int [] a= new int[]{10,6,3,5,6,7,4,3,2,7,6,9,2,9,1,4,7,8};
希尔插入 h=new 希尔插入();
int z=a.length/2;//增量
System.out.println("---排序前---");
for (int i : a) {
System.out.print(i+",");
}
System.out.println();
h.xier(a, z);
System.out.println();
System.out.println("---排序后---");
for (int j : a) {
System.out.print(j+",");
}
}
}
总结
稳定性:
不稳定,按间隔将分成一组,再进行排序,会改变元素的相对顺序
时间复杂度:
希尔排序的时间复杂度依赖于增量序列函数,所以分析起来比较困难,
当n在某个特定范围的时候,希尔排序的时间复杂都约为O(n1.3)。
空间复杂度:
交换顺序时需要一个额外的临时空间,所以为O(1)。