二分插入排序(c语言)

一、什么是二分插入排序?

二分法插入排序,简称二分排序,是在插入第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;
}

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值