相关使用的工具类与接口
运行效率
/**
* 这是插入排序
* 数组长度[2000] 值范围[1-2000] 消耗的时间为[4]毫秒
* 数组长度[4000] 值范围[1-4000] 消耗的时间为[6]毫秒
* 数组长度[8000] 值范围[1-8000] 消耗的时间为[5]毫秒
* 数组长度[16000] 值范围[1-16000] 消耗的时间为[21]毫秒
* 数组长度[32000] 值范围[1-32000] 消耗的时间为[81]毫秒
* 数组长度[64000] 值范围[1-64000] 消耗的时间为[312]毫秒
* 数组长度[128000] 值范围[1-128000] 消耗的时间为[1232]毫秒
* 数组长度[256000] 值范围[1-256000] 消耗的时间为[4903]毫秒
* 数组长度[512000] 值范围[1-512000] 消耗的时间为[19697]毫秒
*/
@Test
public void insertSortTest() {
ArraysSort arraysSort = new InsertSortMethod();
SortHelper.arraySort(arraysSort, 2000, 10);
}
实现类
/**
* 这是优化后的插入排序 减少交换的动作
* 开始只进行值后移 直到找到不能后移的或者索引为0就交换
* * 这是插入排序
* * 2000 长度的数据量消耗的时间为:4毫秒
* * 4000 长度的数据量消耗的时间为:1毫秒
* * 8000 长度的数据量消耗的时间为:7毫秒
* * 16000 长度的数据量消耗的时间为:20毫秒
* * 32000 长度的数据量消耗的时间为:81毫秒
* * 64000 长度的数据量消耗的时间为:324毫秒
* * 128000 长度的数据量消耗的时间为:1256毫秒
* * 256000 长度的数据量消耗的时间为:5006毫秒
* * 512000 长度的数据量消耗的时间为:20057毫秒
* @param ints 排序的数组
*/
@Override
public int[] arraySortMethod(int[] ints) {
for (int i = 1; i < ints.length; i++) {
//记录外循环需要比较的值
int temp = ints[i];
// 这里临时记录最新遍历到的内循环索引id
int nowIndex = -1;
//这里是个倒序遍历 倒叙遍历外循环已经循环了的长度 来一个个对比
for (int j = i - 1; j >= 0; j--) {
//正常判断
if (ints[j] > temp) {
//这里不作数据交换 只对数据进行后移
ints[j + 1] = ints[j];
//nowIndex重新指向最新 下面需要替换的指针
nowIndex = j;
} else {
break;
}
}
//如果不相等说明有数据变更
//把外循环值放到内循环指向最新需要替换的索引上nowIndex
if (nowIndex != -1) {
ints[nowIndex] = temp;
}
}
return ints;
}
/**
* 原版的插入排序 理论上插入排序要比选择排序消耗更少的时间
* 但实际情况反而要多 这是因为swap交换一次就会进行3次赋操作
* 这里是可以优化的
* 1000 长度的数据量消耗的时间为:3毫秒
* 2000 长度的数据量消耗的时间为:3毫秒
* 4000 长度的数据量消耗的时间为:7毫秒
* 8000 长度的数据量消耗的时间为:15毫秒
* 16000 长度的数据量消耗的时间为:62毫秒
* 32000 长度的数据量消耗的时间为:249毫秒
* 64000 长度的数据量消耗的时间为:999毫秒
* 128000 长度的数据量消耗的时间为:3903毫秒
* 256000 长度的数据量消耗的时间为:15424毫秒
*
* @param ints 排序的数组
*/
public int[] oldArraySortMethod(int[] ints) {
for (int i = 1; i < ints.length; i++) {
//记录外循环需要比较的值
int temp = ints[i];
// 临时记录外循环的索引 被插入时被覆盖
int nowIndex = i;
//这里是个倒序遍历 倒叙遍历外循环已经循环了的长度 来一个个对比
for (int j = i - 1; j >= 0; j--) {
//因为已遍历长度是已经是当时排好序的
//如果已遍历长度的值有比temp大
//则进行插入更换 nowIndex重新指向最新已替换指针
//依次循环至索引0
//这里需要注意temp不能改为ints[i],
//在第一次替换后如果是ints[i]比较 指针指向的那个值就为替换后的相对大的那个值
if (ints[j] > temp) {
//索引数据交换
SortHelper.swap(ints, j, nowIndex);
//nowIndex重新指向最新已替换指针
nowIndex = j;
} else {
break;
}
}
}
return ints;
}
/**
* 插入排序在小范围排序效率较高
* 相比并归排序可以减少内存对创建数组的开销
* @param ints 合并数组
* @param l 排序左范围
* @param r 排序右范围
*/
public static void insertSortMethod(int[] ints, int l, int r) {
for (int i = l + 1; i <= r; i++) {
int temp = ints[i];
int swapIndex = -1;
for (int j = i; j > l; j--) {
if (ints[j - 1] > temp) {
ints[j] = ints[j - 1];
swapIndex = j - 1;
} else {
break;
}
}
if (swapIndex != -1) {
ints[swapIndex] = temp;
}
}
}