【C语言】有序数组的折半查找(完整代码)

题目描述:

在一个整型的有序数组中查找某个数字,若找到了就返回当前元素位置,找不到则返回 - 1。
题目分析:
在数组中找到某个值,我们首先想到的方法可能是直接顺序遍历,这是最简单的方法,但是效率不一定高。如果当前给定数组是乱序的,我们只能通过挨着遍历的方法查找某个数。

但当前数组是一个有序数组,我们是否有效率更高的方法呢?这就要介绍一下“折半查找”

主要思想:

折半查找:先通过计算数组的元素个数,找到数组的中间位置。然后将目标数字与数组的中间元素进行比较,若目标数字比它小则在它的左部分按折半查找继续,若目标数字比它大则在它的右部分按折半查找继续,直至到结果,输出位置或者-1。(位置=下标+1)

代码实现思想:

int bin_search(int arr[], int key, int sz)   //arr传入数组,key目标值,sz数组元素个数
    {
    	int left = 0;    //定义左边下标
    	int right = sz - 1;    //定义右边下标
 
    	while (left <= right)    //循环条件
    	{
    		if (key > arr[(left + right) / 2])    //目标值>中间值
    		{
    			left = (left + right) / 2 + 1;  //向右半边查找,左边坐标更新
    		}
    		else if (key < arr[left + (right - left) / 2])    //目标值<中间值
    		{
    			right = left + (right - left) / 2 - 1;   //向左半边查找
    		}
    		else                               //目标值=中间值
    		{
    			return (left + (right - left) / 2 + 1);  //返回下标值+1
    		}
    	}
    	return  -1;   //while 循环结束未找到,则返回-1
    }

解题完整代码:

通过对以上思想的理解,我们便很容易应用到这道题目上。

    #define _CRT_SECURE_NO_WARNINGS 1
    #include <stdlib.h>
    #include <stdio.h>
    #define N 10
    int bin_search(int arr[], int key, int sz)  //折半查找方法
    {
    
    	int left = 0;
    	int right = sz - 1;
    
    	while (left <= right)
    	{
    		if (key > arr[(left + right) / 2])
    		{
    			left = (left + right) / 2 + 1;
    		}
    		else if (key < arr[left + (right - left) / 2])
    		{
    			right = left + (right - left) / 2 - 1;
    		}
    		else
    		{
    			return (left + (right - left) / 2 + 1);
    		}
    	}
    	return  -1;
    }
    
    int main()
    {
    	int i = 0;
    	int k = 0;
    	int sz = 0;
    	int a[N] = { 0 };
    	printf("请输入%d个数:", N);
    	for (i = 0; i < N; i++)
    	{
    		scanf("%d", &a[i]);
    	}
    	sz = sizeof (a) / sizeof (a[0]);
    	printf("\n请输入想查找的数:");
    	scanf("%d", &k);
    	int ret = bin_search(a, k, sz);   //方法调用
    	if (ret >= 0)
    	{
    		printf("\n你想要的数在第%d位!\n", ret);
    	}
    	else
    		printf("\n数组中无此数!\n");
    	return 0;
    }

执行结果与简单说明:

在这里插入图片描述
关注博主,有更多精彩的内容哦~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值