希尔排序 对插入排序的优化
因为当如果插入排序中最小的元素位于最后一位时,就需要不断的进行循环判断,直到第一位,非常影响效率
package datastructure.sort;
/*
@CreateTime 2021/9/13 11:12
@CreateBy cfk
*/
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class ShellSort {
public static void main(String[] args) {
// 测试80000条数据 冒泡排序所需要的时间
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i] = (int) (Math.random()*8000000);
}
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
String s1 = sdf.format(new Date());
System.out.println(s1);
shellChange(arr);
String s2 = sdf.format(new Date());
System.out.println(s2);
// int[] arr = {1,0,5,7,8,4,6,9,2,3};
//
// moveShell(arr);
//
// System.out.println(Arrays.toString(arr));
}
//按照一定的步长通过交换法完成数组的插入 遍历80000数据7s
public static void shellChange(int[] arr){
//每次以数据一半作为步长 进行判断
for (int step = arr.length/2; step > 0; step /= 2){
int tmp;
//从步长后半段数据开始遍历
for (int i = step; i < arr.length; i++) {
//以同样的步长进行遍历
for (int j = i - step; j >= 0; j -= step) {
//如果当前元素对应步长后的元素大 则更换两者的位置
if (arr[j] > arr[j+step]){
tmp = arr[j];
arr[j] = arr[j+step];
arr[j+step] = tmp;
}
}
}
}
}
//按照一定的步长通过交换法完成数组的插入 遍历80000数据6s
public static void shellChange2(int[] arr){
//Knuth 克努特 序列选取间隔 提高效率
int jiange = 1;
while (jiange<= arr.length/3){
jiange = jiange*3+1;
}
//每次以数据一半作为步长 进行判断
for (int step = jiange; step > 0; step = (step-1)/3){
int tmp;
//从步长后半段数据开始遍历
for (int i = step; i < arr.length; i++) {
//以同样的步长进行遍历
for (int j = i - step; j >= 0; j -= step) {
//如果当前元素对应步长后的元素大 则更换两者的位置
if (arr[j] > arr[j+step]){
tmp = arr[j];
arr[j] = arr[j+step];
arr[j+step] = tmp;
}
}
}
}
}
//按照一定的步长通过交换法完成数组的插入 遍历80000数据1s
public static void moveShell(int[] arr){
for(int step = arr.length/2; step > 0; step /= 2){
for (int i = step; i < arr.length; i++) {
//把需要插入的元素保存在一个变量里
int insertVal = arr[i];
//给被插入元素一个初值
int insertIndex = i - step;
//只有当后面的元素小于前面的元素时才进行此运算 这里主要为了避免如果已经按顺序排列了在排序
if (arr[insertIndex+step]<arr[insertIndex]){
//如果被插入数 相隔同样 步长还有数据则进行下面的运算
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex+step] = arr[insertIndex];
insertIndex -= step;
}
//当退出while,就把temp赋值
arr[insertIndex+step] = insertVal;
}
}
}
}
}