什么是希尔排序?
希尔排序是希尔提出的一种排序算法,希尔排序也是一种插入排序,它是简单插入排序经过改进后的一个更高效的版本,也称为缩小增量排序。
希尔排序按照增量将数组进行分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,没组包含的关键词越来越多,当增量减至1时,整个文件被分成一组,算法便终止
希尔排序代码思想:
假设有一个数组arr[],里面有十个元素
第一次: gap=arr.length/2=5,将数组分为五组,每个数组元素的索引相差5(步长为5),然后每组进行排序
第二次:gap=gap/2=2;将数组分为两组,每个数组元素的索引相差2(步长为2),然后每组进行排序
第三次:gap=gap/2=1;将数组分为一组,每个数组元素的索引相差1,对于交换法而言,这就是异常冒泡排序
希尔排序代码实现(交换法):
public static void ShellSort(int[] arr){
int temp=0;
int count=0;
//gap(步长)等于数组的长度除以2(5,2,1)
for (int gap=arr.length/2;gap>0;gap/=2){
for (int i = gap; i < arr.length; i++) {
//试想如果j的下标等于这组之前的那个元素的小标加上gap(步长),就减去这个步长与之比较(画图清秀)
for (int j = i-gap; j>=0 ; j-=gap) {//这句话就是遍历每组中的元素,让每组中的元素比较
if (arr[j]>arr[j+gap]){
temp=arr[j+gap];
arr[j+gap]=arr[j];
arr[j]=temp;
}
}
}
System.out.println("希尔排序第"+(++count)+"轮="+ Arrays.toString(arr));
}
}
但是基于交换法实现希尔排序的速度太慢了,所以我们要编写一个基于插入法的希尔排序算法
希尔排序插入法:
1,记录当前位置的元素值int temp=arr[j];从当前元素的前一个位置开始,往前寻找,每次移动gap个距离。
2,如果arr[temp-gap]>temp:
将数组元素后移,腾出空间:arr[j]=arr[j-gap](元素索引往后移动gap);
然后继续往前找:j-=gap;看看是不是比前面还小
如果temp>arr[j-gap],找到插入位置,执行插入arr[j]=temp;
如果找到数组最前面还是没有找到插入位置:j-gap<0,则证明temp需要插入在数组最前面
public static void ShellSort2(int[] arr){
for (int gap=arr.length/2;gap>0;gap/=2){
for (int i = gap; i <arr.length ; i++) {
int j=i;
int temp=arr[j];
if (arr[j-gap]>arr[j]) {
while (j - gap >= 0 && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;//遍历每组前面的
}
}
//temp比arr[j-temp]大,索引插入在j的位置
arr[j]=temp;
}
}
}