[插入排序-希尔排序]
前言(不重要):希尔排序是希尔这个人提出的,又名缩小增量排序,是改进版的插入排序
1.算法思想
- 优先比较距离远的元素,将数组元素拆分之后再进行插入排序
- 以length/2作为增量n,比较a[i + n]、a[i],若a[i + n]较小,交换a[i + n]与a[i]
- 缩小增量n /= 2 ,比较a[i + n]、a[i]、a[i - n]…,若a[i + n]比其他都小,则提到最前面
- 当n = 1时,即对整个数组进行插入排序
2.流程分析
直接上例子:int[] a = {6 , 1 , 4 , 7 , 10 , 2 , 9 , 3 , 5 , 8}
- 增量n=10/2
比较a[5]、a[0]
比较a[6]、a[1]
比较a[7]、a[2]
比较a[8]、a[3]
比较a[9]、a[4]
===> [2, 1 , 3 , 5 , 8 , 6 , 9 , 4 , 7 , 10] - 增量n=5/2,
比较a[2]、a[0]
比较a[3]、a[1]
比较a[4]、a[2]、a[0]
比较a[5]、a[3]、a[1]
…
比较a[9]、a[7]、a[5]、a[3]、a[1]
===> [2, 1 , 3 , 4 , 7 , 5 , 8 , 6 , 9 , 10] - 增量n=2/2,对整个数组进行插入排序
比较a[9]、a[8]、a[7]、a[6]、a[5]、a[4]、a[3]、a[2]、a[1]、a[0]
===> [1, 2 , 3 , 4, 5 , 6 , 7 , 8 , 9 , 10]
3.动态排序图
- 省略
4.代码实现
public static void shellSort(int[] array){
//定义gap作为增量
int gap = array.length/2;
//控制下标在数组范围内
while(gap > 0){
//从增量下标开始
for (int i = gap; i < array.length ; i++) {
//用临时变量temp存放取出值
int temp = array[i];
//待比较元素下标Id
int preId = i - gap;
//比较增量间的2个值
while(preId >= 0 && array[preId] > temp){
array[preId + gap] = array[preId];
//a[9]依次与a[9-gap]比较
preId -=gap;
}
//当a[9] > a[3]时,将a[9]插入a[3]后,也就是a[3+gap]的位置
//此时a[9]=a[7],a[7]=a[5],a[5]就用来存放a[9]的值
array[preId + gap] = temp;
}
gap = gap/2;
}
}
总结:理解≠学会,一定要打断点,debug逐步调试,手动敲一遍代码!!!