1.希尔排序含义
希尔排序是希尔1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破On(2)的第一批算法之一。它与插入排序不同之处在于,它会优先比较距离较远的元素。
2.理解排序过程
- 初始增量gap=length(数组长度)/2=5,那么整个数组分为5组,[8,3] [9,5] [1,4] [7,6] [2,0],
- 对这个5组的数据分别进行直接插入排序(也就是比对交换),第一组[8,3] 就变成[3,8],第二组[9,5]变成[5,9],第三组[1,4]保持位置不动,依次类推直到完成第一轮数据的交换[3,8][5,9][1,4][6.7][0,2]。
- 再缩小增量gap=5/2=2那么数组就会分成2组[3,1,0,9,7]和[5,6,8,4,2],进行比对排序,排序以后[0,1,3,7,9]和[2,4,5,6,8]
- 继续缩小增量gap=2/2=1就分为一组[0,2,1,4,3,5,7,6,9,8],进行对比交换就有序了。
3.排序代码示例
package com.test.sort.simpleSort;
import java.util.Arrays;
/**
* @Author df
* @Date 2019/8/8 9:27
* @Version 1.0
* 希尔排序
* 第一次循环之前先做一个增量=数组长度/2的操作,然后有一个当前坐标和一个增量的坐标,用当前作坐标和增量坐标来比对
* 如果当前坐标大于增量的坐标,那么就进行插入排序,然后进行当前坐标-增量值为了防止死循环,也是为了-增量找寻原来的位置
* 进行插入适当的值(while外面的,arr[preIndex + gap]=temp),当全部循环完毕,载进行增量/2 ,再一次的进行比对
* 直到gap=0.循环完毕
*/
public class XIERSort {
public static void main(String[] args) {
int[] arr = {6, 9, 8, 1, 5, 3, 4, 2, 0};
sort(arr);
}
// 官方的希尔排序
public static void sort(int[] arr) {
//定义数组长度
int length = arr.length;
int temp, gap = length / 2;
// 为了能进行gap每次进行计算时还能进入循环
while (gap > 0) {
for (int i = gap; i < length; i++) {
temp = arr[i];
// 上一个元素,第一次循环是为了目标确保是5那个差
int preIndex = i - gap;
// 此时i=5,temp=3,经过运算5-5=0,找到数字6,比对后面的数字小于前面的进行交换
while (preIndex >= 0 && arr[preIndex] > temp) {
arr[preIndex + gap] = arr[preIndex];
// 防止死循环,是因为每次都是增量的所以需要-gap
preIndex = preIndex - gap;
}
// 如果不用发生计算需要把临时变量赋给不用变化的当前值,如何是发生whIle循环里的
// 计算也能找到相应的数字进行临时变量交互数据
arr[preIndex + gap] = temp;
}
gap = gap / 2;
}
System.out.println(Arrays.toString(arr));
}
}
4.算法分析
还是借用漫画图把