最近在学习希尔排序的过程中,感觉有一点困惑,虽然他的核心思想容易理解,就是为了减少插入排序中顺序不一致时需要后移发生的交换次数。
希尔排序采用分组的方法解决了上述问题,通过不断的减小步长来达到逐步排序的效果,当步长为1的时候,其实就是简单插入排序了。
下面在代码中进行详解:
public static int[] shell(int []arr) {
for (int step = arr.length / 2; step > 0; step /= 2) {//定义步长,先取步长为数组长度的二分之一,逐步减小,最后为1
int temp=0;//用来存储要插入的元素
int index=0;//用来存储要插入元素的索引
for (int i = step; i < arr.length; i++) {//插入排序的时候我们是从索引为1的元素开始,默认索引为0的元素有序
//现在分成这么多组,就把索引为0到step-1的元素默认有序,从step的元素开始,因为我们默认这么多组的开头元素有序
//步长为1的时候也是默认开头元素有序,只是就一个组罢了
temp = arr[i];//记录要插入元素的值
index=i;//记录要插入元素的索引,为什么要定义index来保存i呢?会不会多此一举
while (index-step>0&&temp<arr[index-step]) {//如果要插入的元素大于本组的前一个元素,就把前一个元素后移
//并且找到最终要插入位置的索引
//这里应该先判断index-step是否大于0,因为如果先判断arr[index-step]可能会出现索引越界
arr[index] = arr[index - step];//后移
index-=step;//这里就解释了为什么要定义index了,因为index会不断变化,最终指向元素要插入的位置
}
arr[index]=temp;//在while中找到要插入的位置index了,此时将元素插入
}
}
return arr;
}