四、希尔排序
———针对数量巨大时,再用插入排序则显得低效。故对插入排序进行升级,希尔排序也称为递减增量排序算法。
package com.xu.Array;
import java.util.Arrays;
//希尔排序
public class Demo01 {
public static void main(String[] args) {
int[] arr=new int[25];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*100);
}
System.out.println("排序前:"+ Arrays.toString(arr));
shellSort(arr);
System.out.println("排序后: "+Arrays.toString(arr));
}
private static void shellSort(int[] arr) {
for(int h=arr.length/2;h>0;h/=2){ //第一次的增量选择数组长度的一半
for(int i=h;i<arr.length;i++){
for(int j=i;j>h-1;j-=h){
if(arr[j]<arr[j-h]){
swapValue(arr,j,j-h);
}
}
}
}
}
private static void swapValue(int[] arr, int j, int i) {
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
上诉代码排序的方法内,第一次选取的间隔为数组长度的一半。
也可以利用克努特序列确定间隔:
int h=1; //间隔初始为1时
h=h*3+1;// h 为数组长度
package com.xu.Array;
import java.util.Arrays;
//希尔排序
public class Demo02 {
public static void main(String[] args) {
int[] arr=new int[25];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*100);
}
System.out.println("排序前:"+ Arrays.toString(arr));
int interval=1;
while(interval<=arr.length/3){
interval=interval*3+1;
}
for(int h=interval;h>0;h=(h-1)/3){ //第一次的增量选择用克努特排序
for(int i=h;i<arr.length;i++){
for(int j=i;j>h-1;j-=h){
if(arr[j]<arr[j-h]){
swapValue(arr,j,j-h);
}
}
}
}
System.out.println("排序后: "+Arrays.toString(arr));
}
private static void swapValue(int[] arr, int j, int i) {
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
个人理解:希尔排序就是间隔为1的插入排序,但效率比直接插入法效率高。