希尔排序算法
介绍
希尔排序也是一种插入排序,它是简单插入排序经过改进后的一个高效的版本,也称缩小增量排序
基本思想
希尔排序法基本思想
是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;
随着增量的逐渐减少,每组包含的关键词越来越多,当增量减至一时,
整个文件被分为一组,算法变终止
图解
代码(交换式和移位式)
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
//shellSort(arr);//交换式
shellSort2(arr);//移位式
}
//交换式希尔排序
public static void shellSort(int[] arr) {
int temp = 0;
int count = 0;
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; i++) {
//遍历各组中所有元素(共gap组,步长gap)
for (int j = i - gap; j >= 0; j -= gap) {
//如果当前元素大于加上步长后的那个元素,就交换
if (arr[j] > arr[j + gap]) {
temp = arr[j];
arr[j] = arr[j + gap];
arr[j + gap] = temp;
}
}
}
count++;
System.out.println("希尔排序第" + count + "轮=" + Arrays.toString(arr));
}
}
//对交换式的希尔排序进行优化-》移位法
public static void shellSort2(int[] arr){
int count=0;
//增量gap, 并逐步的缩小增量
for (int gap = arr.length / 2; gap > 0; gap /= 2){
//从gap个元素,逐个对其所在的组进行直接插入排序
for (int i = gap;i<arr.length;i++){
int j =i ;
int temp = arr[j];
if (arr[j] < arr[j-gap]){
while (j-gap >=0&& temp<arr[j-gap]){
//移动
arr[j] = arr[j-gap];
j-=gap;
}
//当退出white循环后,就给temp找到插入的位置
arr[j] =temp;
}
}
count++;
System.out.println("希尔排序第" + count + "轮=" + Arrays.toString(arr));
}
}
}
结果
希尔排序第1轮=[3, 5, 1, 6, 0, 8, 9, 4, 7, 2]
希尔排序第2轮=[0, 2, 1, 4, 3, 5, 7, 6, 9, 8]
希尔排序第3轮=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
速度测试
交换式
public static void main(String[] args) {
//int[] arr = {8,9,1,7,2,3,5,4,6,0};
//创建要给80000个随机的数组
int[] arr = new int[80000];
for (int i =0;i<80000;i++){
arr[i] =(int) (Math.random()*8000000);//生成一个[0,8000000);
}
System.out.println("排序前");
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间="+date1Str);
shellSort(arr);//交换式
//shellSort2(arr);//移位式
System.out.println("排序后");
Date date2 = new Date();
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序前的时间="+date2Str);
// System.out.println(Arrays.toString(array));
}
结果
排序前
排序前的时间=2021-01-24 00:32:26
排序后
排序前的时间=2021-01-24 00:32:32
移位式
public static void main(String[] args) {
//int[] arr = {8,9,1,7,2,3,5,4,6,0};
//创建要给80000个随机的数组
int[] arr = new int[80000];
for (int i =0;i<80000;i++){
arr[i] =(int) (Math.random()*8000000);//生成一个[0,8000000);
}
System.out.println("排序前");
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间="+date1Str);
// shellSort(arr);//交换式
shellSort2(arr);//移位式
System.out.println("排序后");
Date date2 = new Date();
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序前的时间="+date2Str);
// System.out.println(Arrays.toString(array));
}
结果
排序前
排序前的时间=2021-01-24 00:34:57
排序后
排序前的时间=2021-01-24 00:34:57