建议先看懂直接插入排序 https://blog.csdn.net/qq_43665697/article/details/98651903
二分插入排序是在插入排序的基础上利用二分法对算法进行的优化减小比较次数 但是插入流程和直接插入排序是一样的
对待插入位置i 的左边元素进行二分查找 也就是 left 设置为0 right 设置为 i+1 然后取中间位置mid 的值和待插入元素的值进行判断如果比它小则说明待插元素在 mid 的右边 让 left = mid+1继续循环寻找;
如果比它大则说明待插元素在 mid 的左边 让right = mid-1继续循环寻找
直到 left<= right 条件不再满足 这样跳出循环 此时left的位置一定是待插入元素要插入的位置
然后对 [left,i-1]之间的元素进行右移一位 然后再把待插入元素插入到left位置即可
(相对于插入排序优化的点 就是找待插入元素的位置 找中间值进行比较麻 肯定会比一个一个人找快)
以数组a[]=[2, 3, 8, 7, 1] 待插入元素a[3] =7 为例 走一遍
第一次 left = 0, a[0]=2 right =2, [2]=8 left<=right 满足条件 然后找mid位置的值和 a[3] 进行比较
mid=(0+2)/2=1 a[1] 和待插入元素a[3]进行比较 3<7 说明待插入元素a[3] 在mid的右边 则让 left=mid+1
此时 left =2 right = 2 left<=right 满足条件 继续找mid位置和a[3]进行比较
mid=(2+2)/2=2 a[2] 和待插入元素a[3]进行比较 8>7 说明待插入元素a[3] 在mid的左边 则让 right =mid-1
此时 left =2 right = 1 left<=right 不满足条件 此时left则为元素a[3] 要插入的位置】
然后对 [left,i-1]之间的元素进行右移一位 此时a[]=[2, 3, 8, 8, 1]
然后在把待插入元素插入在 left位置 此时a[]=[2, 3, 7, 8, 1] 此次插入结束
循环此过程即可得到一个升序的有序数组 二分插入排序和简单插入排序 每次过程结果都一样 只是对查找待插入元素的位置进行了优化 所以大家在笔试过程中按简单插入排序推导即可
package test1;
import java.util.*;
public class Demo {
public static void main(String[] args) {
int a[] = { 8, 3, 2, 7, 1 };
for (int i = 1; i < a.length; i++) {
int temp = a[i];
int left = 0;
int right = i - 1;
int mid = 0;
// 不满足条件跳出 left则为要插入的位置
while (left <= right) {
mid = (left + right) / 2;
// temp < a[mid] 则 待插入元素应为 mid左边
if (temp < a[mid]) {
right = mid - 1;
// temp >a[mid] 则 待插入元素应为 mid右边
} else {
left = mid + 1;
}
}
// 对 [left,i-1]之间的元素进行右移一位
for (int j = i - 1; j >= left; j--) {
a[j + 1] = a[j];
}
// 待插入元素插入到left位置
if (left != i) {
a[left] = temp;
}
System.out.println(Arrays.toString(a));
}
}
}