希尔排序
前言
本章内容对希尔德原理及特点并没有做太多叙述,主要目的是对希尔排序代码进行
详细解释,百度的代码大多没有详解,这里加了许多注释,帮助读者理解代码,从而理
解希尔排序内容
简介
希尔排序是插入排序的一种,也成缩小增量排序,是直接插入排序算法的
一种更高效的改进版本;
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入算法排序,
每组包含的元素越来越多,当增量减至1.整个数组恰被分成一组,
算法便终止
排序过程
缩小增量
希尔排序属于插入类排序,是将整个有序序列分位
若干个小的子序列分别进行插入排序;
排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;
然后取d2<d1,重复上述分组和排序操作;
直至di=1,即所有记录放进一个组中排序为止;
代码实现
public static void main(String[] args) {
int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1}; //排序前数组
int d = a.length; //用d接收数组长度
while (true) { //条件永远为真,不断进行循环,用break跳出循环
d = d / 2; //判断分隔多少个数为一组,比如d=6,则下标为0,6,12的分一组,下标为1,7的分一组,2,8为一组
//当d=3时,下标为0,3,6,9,12为一组,下标为1,4,7,10为一组,2,5,8,11为一组
//当d=1时,0,1,2,3,4,5,6,7,8,9,10,11,12为一组
for (int i = 0;i < d;i++ ) { //第一次while循环,d=6时,一共分6组,所有i<6,数组下标从0开始,每组内的第一个元素下标分别为0,1,2,3,4,5,用i表示,进行6次for循环,每次循环将这组内的数据排好序
//第二次while循环时,d = 3,一共分3组,此时i<3,进行三次循环,每组内的第一个元素下标分别为0,1,2,利用for循环,每次循环将这组内的数据排好序
for(int j = i + d;j < a.length;j = j + d) { //第一次while循环,共分6组,此次for循环,找到每一组的第二个元素
//先将j赋值,再判断j与a.length的大小,i+1是这组循环中的第二个元素,之所以先i+1是为了
//确保进入循环体时,下一个元素存在
int temp = a[j]; //用temp保留欲插入元素的值,下面排序时使用直接插入排序,数组元素会后移,将后面一位元素覆盖
int k; //定义一个初始值,便于与其他变量分离开
for(k = j - d;k >= 0 && temp < a[k];k = k - d ) {
//k >= 0 需要在&&符合前面,因为&&符合存在短路现象,k<0时.a[k]下标越界了,需要被短路,从而保证代码正常执行
//直接插入排序,将这组内的数据进行比较,(后移覆盖)
a[k + d] = a[k];
}
a[k + d] = temp; //for循环时,k=k-d,执行完毕后,判断条件不成立,循环结束,但未执行循环体,所以这里要k+d而不是k
}
}
if(d == 1) { //d=1时,元素间隔为0,即所有元素分成一组,且已排序完成.故跳出循环
break;
}
}
System.out.println("排序后:"); //打印已知数组
for(int i = 0; i < a.length;i++)
{
System.out.print(a[i] + " ");
}
}
小结
代码中德变量 i,j,k还是比较绕的,需要耐心理解,本章主要帮助读者理解代码内容
,至于原理,很多网页均有详细说明.