插入排序
插入排序的基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
1、直接插入排序
// 直接插入排序的算法思路:
// (1) 设置监视哨arr[0],将待插入记录的值赋值给arr[0];
// (2) 设置开始查找的位置j;
// (3) 在数组中进行搜索,搜索中将第j个记录后移,直至arr[0]≥arr[j]为止;
// (4) 将arr[0]插入arr[j + 1]的位置上。
// 直接插入排序算法:
public zjinsert(arr: number[]): void {
let len = arr.length;
for (let i = 1; i < len; i++) {
let temp = arr[i];
let j = i - 1;//标记j
while (j > -1 && temp < arr[j]) {//在arr[0]-arr[j-1]之间是有序的,单满足这个j > -1 && temp < arr[j]条件是位置右移
arr[j + 1] = arr[j]; //当不满足条件是说明找到了位置,循环结束
j--;//标记-1
}
arr[j + 1] = temp;//标记点赋值
}
}
2、折半查找插入,在插入过程的查找过程用上二分查找
// 折半插入排序的算法思想:
// 算法的基本过程:
// (1)计算 0 ~ i - 1 的中间点,用 i 索引处的元素与中间值进行比较,如果 i 索引处的元素大,说明要插入的这个元素应该在中间值和刚加入i索引之间,反之,就是在刚开始的位置 到中间值的位置,这样很简单的完成了折半;
// (2)在相应的半个范围里面找插入的位置时,不断的用(1)步骤缩小范围,不停的折半,范围依次缩小为 1/ 2 1/ 4 1/ 8 .......快速的确定出第 i 个元素要插在什么地方;
// (3)确定位置之后,将整个序列后移,并将元素插入到相应位置。
public binaryInsert(arr: number[]): void {
let len = arr.length;
for (let i = 1; i < len; i++) {
let tmp = arr[i], left = 0, right = i - 1;
//用二分法找到最接近待排序的temp的值得位置下标
while (left <= right) {
let mid = Math.ceil((left + right) / 2);
if (tmp < arr[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
}
//容错
for (let j = i - 1; j >= left; j--) {
arr[j + 1] = arr[j];
}
//进行标记点赋值
arr[left] = tmp;
}
}
3、希尔排序法
参考:https://blog.csdn.net/u013270347/article/details/80604690