什么是折半插入排序?
因为直接插入排序在数据集完全无序(要求升序,数据集却是降序)时,对待插入数据插入位置的查找时间复杂度太高。
所以我们引出折半插入排序,它在针对无序的数据集时,效果更好。
核心思想-二分查找
寻找插入位置时,从已排序区间的中间值开始比较
low-已排序区间的第一个值
high-已排序区间的最后一个值
mid-已排序区间的中间值
i待排序的第一个值
循环条件:high>low 终止条件:high>low i插入high的下一个位置
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
数据 | 1 | 5 | 7 | 9 | 8 | 2 | 4 | 3 |
初始 | l | m | h | i | ||||
i>m h>l | l/m | h | ||||||
i<m h=l | h/l/m | |||||||
h=h-1 i=h+1 | h | l |
优缺点
折半插入排序在无序集情况下优于直接排序。但在近似有序集下,优于折半插入排序比较次数较多。因此最好情况下的直接插入排序要优于折半插入排序。
复杂度和稳定性都与直接插入排序相同
实现代码
public static void shellSort(int[] array) {
int n = array.length;
if (n <= 1) {
return;
} else {
int step = n / 2;
while (step >= 1) {
for (int i = 1; i < n; i++) {
int temp = array[i];
int j = i - step;
for (; j >= 0; j-=step) {
if (temp < array[j]) {
array[j + step] = array[j];
} else {
break;
}
}
array[j + step] = temp;
}
step /=2;
}
}
}