一、什么是二分插入排序?
二分法插入排序,简称二分排序,是在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们中间的那个元素比,如果小,则对前半再进行折半,否则对后半进行折半,直到left<right,然后再把第i个元素前1位与目标位置之间的所有元素后移,再把第i个元素放在目标位置上。(出自百度搜素)。
二、二分查找
想要彻底弄明白二分插入排序,就首先要知道什么是二分查找法。
首先我们先来说说什么是二分查找法,说白了就是折中查找。什么是折中查找呢?
如图:
折中查找就是在一个数组查找到一个元素的位置(记住所查找的元素必须是一个升序的数组)。
图中第一步定义的min 和 max 分别对应的是下标最小值和小标最大值,num所对应的是min+max的折中取整值。
第二步拿所要查找的元素与数组中下标为num的元素进行大小比较。当查找元素 > a[num]时,那么min = num + 1,为什么min的值会变成num + 1?因为通过比较可知查找元素是在a[num]元素的右边,所以min就要更新为num + 1,且max值不变。当查找元素 < a[num]时,max 的变化原理与min值变化原理相同。当查找元素 == a[num]时,就说明你所要查找的元素已经找到,可以将其打印出来,并停止循环。
通过while循环第二步,其中num的值需要放在循环中,循环停止条件是在min > max时停止循环。
第三步当循环停止时,且min > max时,就说明在数组中是找不到你要查找的数字。
while(min <= max)
{
int num1 = (min+max) / 2;
if(num < i[num1])
{
max = num1-1;
}
else if(num > i[num1])
{
min = num1+1;
}
else
{
printf("%d\n",i[num1]);
break;
}
}
if(min > max)
{
printf("查询不到这个数\n");
}
三、二分插入排序过程
了解完二分查找后,我们就来说说什么是二分插入。想知道二分插入排序,我建议是可以先去了解一下什么是插入排序,两者的区别在于怎样找到插入的位置。
插入排序的插入位置是可以自己设置的,数组中想插入到哪就插入到哪,前提是这个数组要大,对升序降序没有要求。
而二分插入排序的插入位置是通过二分查找找到的,前提是这个数组也要够大,而且这个数组必须是一个升序的数组才能进行二分插入排序。
通过二分查找我们可知当min > max时是说明这个数组中是没有你要查找的数字,而在二分插入排序中当 min > max时,就是找到了插入的位置,插入的位置的下标等于min,且在二分查找的过程中就不需要写 = 的情况了
例:定义一个升序的数组 a[8] = {11,24,35,46,59,67,78}。其中我要向数组插入47。
11,24,35,46,59,67,78 |
通过改良二分查找,可以得到 最终跳出循环后min = 4,那么47最终插入的位置就为下标 = 4的位置,原先插入位置的元素和后面的元素全部向后移动一位。
所以最终的结果{11,24,35,46,47,59,67,78}
四、代码完整过程
#include <stdio.h>
int arr_num_lp(int *p,int n,int m)//查找插入位置
{
int min = 0;
int max = n - 1;
int temp = m;
while(min <= max)
{
int num = (min + max) / 2;
if(temp < p[num])
{
max = num - 1;
}
else
{
min = num + 1;
}
}
return min;
}
void arr_ist_sort(int *p,int n,int m)//元素后移
{
int i = 0;
for(i = 7;i >= m;i--)
{
p[i] = p[i] ^ p[i + 1];
p[i + 1] = p[i] ^ p[i + 1];
p[i] = p[i] ^ p[i + 1];
}
p[m] = n;
}
void arr_out(int a[9])//将数组输出
{
int i = 0;
for(i = 0;i < 9;i++)
{
printf("%d ",a[i]);
}
printf("\n");
}
int main()
{
int a[9] = {0};
int i = 0;
printf("请输入一个递增的数组\n");
for(i = 0;i < 8;i++)
{
scanf("%d",&a[i]);
}
printf("请输入你要插入的数字:\n");
int j = 0;
scanf("%d",&j);
int min = arr_num_lp(a,9,j);//调用查找位置函数
arr_ist_sort(a,j,min);//调用位置交换元素
arr_out(a);//调用数组输出函数
return 0;
}