【c语言】二分查找

二分查找的用处

在⼀个有序的数组中查找指定的数字n,很容易想到的方法就是遍历数组,但是这种方法效率比较低。

例如:

#include <stdio.h>
int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    int k = 7;
    int i = 0;
    int sz = sizeof(arr)/sizeof(arr[0])
    for(i = 0;i < sz; i++)
    {
        if(arr[i] = k)
        {
            printf("找到了,下标是%d\n",i);    
            break;
        }
    }
    if(i == sz)
    {
        printf("找不到\n");
    }    


    
    return 0;
}

这样遍历会很慢,比如我买了⼀双鞋,你好奇问我多少钱,我说不超过300元。你还是好奇,你想知道到底多少,我就让你猜,你会怎么猜?你会1,2,3,4...这样猜吗?显然很慢;⼀般你都会猜中间数字,比如:150,然 后看大了还是小了,这就二分查找,也叫折半查找

二分查找的原理图解 

例如,在有序数组arr[]={0,1,2,3,4,5,6,7,8,9,10}中查找7

初始状态:

第一轮查找:根据(left+right)/2 = 4,下标4的位置是5,5<7所有可以判定 7 位于 5 右侧的区域,更新搜索区域为元素 5 右侧的区域。

第二轮查找:根据(left+right)/2 = 7,下标7的位置是8,8>7所有可以判定 7 位于 8 左侧的区域,更新搜索区域为元素 8 左侧的区域。

第三轮查找: 根据(left+right)/2 = 5,下标5的位置是6,6<7所有可以判定 7 位于 6 右侧的区域,更新搜索区域为元素 6 右侧的区域。

第四轮查找: 搜索区域内中间元素的位置是 [(6+6)/2]=6,因此中间元素是 7,此元素就是要找的目标元素

  代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//左边界下标
	int left = 0;
	//右边界下标
	int right = sizeof(arr) / sizeof(arr[0]) - 1;
	//要找的数字 
	int key = 7;
	//记录中间元素的下标 
	int mid = 0;
	int find = 0;
	// 当左边界还未超过右边界时,进行二分查找
	while (left <= right) 
	{
		mid = (left + right) / 2;// 每次循环重新给mid赋值,改变中间值的下标
		// 如果中间值大于目标值,说明目标值在左半边,此时改变右边界的下标(缩减右半边)
		if (arr[mid] > key)		
		{
			right = mid - 1;
		}
		// 如果中间值小于目标值,说明目标值在右半边,此时改变左边界的下标(缩减左半边)
		else if (arr[mid] < key)
		{
			left = mid + 1;
		}
		// 如果都不满足,说明查找成功,此时跳出循环
		else
		{
			find = 1;
			break;
		}
	}
	if (1 == find)
		printf("找到了,下标是%d\n", mid);
	else
		printf("找不到\n");
}

求中间元素的下标,使用 mid = (left+right)/2 ,如果left和right比较大的时候可能存在问题,可以使用下面的方式:

mid = left+(right-left)/2;

感谢各位读者的观看。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值