二分查找法详解与C语言实现(递归与非递归)

目录

一、二分查找法

二、时间复杂度 

三、C语言代码实现

1、递归实现

2、非递归实现

3、完整代码


嗨,感谢你打开这篇文章!👋 如果阅读中发现任何笔误或表述不清的地方,欢迎随时留言告诉我~你的视角会让内容变得更完善!

一、二分查找法

        如果我们有一组有序序列,以升序为例,我们要从这组升序序列里面查找一个数,假设我们要找的数为x,我们先将x与这组有序数列里面最中间的那个数进行比较,如果要查找的数比中间这个数小,就说明我们要查找的数在中间这个数的左边部分,我们在将要查找的数与左边部分的最中间的那个数进行比较,如果比左边部分最中间的数大,那就说明我们要查找的数在这个最中间数的右边部分,我们在将要查找的数与右边部分中间的数进行比较,重复这种方法,直到找到我们要查找的数,每次我们将要查找的数与最中间的那个数进行比较后,大于就在右边部分继续查找,小于就在左边部分查找,我们就发现每次都能缩小一半的查找范围,这种方法我们就称为二分查找法,也叫做折半查找。

基本逻辑:二分查找(Binary Search)是一种在有序数组中查找某一特定元素的查找算法。查找过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则查找过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。

举例{5,13,19,21,37,56,64,75,80,88,92}采用二分查找算法查找关键字为 21 的过程为:

(1)找到中间值

(2)21比中间值小,则在左半部分找中间值 

(3) 比中间值大,则在右半部分找中间值

二、时间复杂度 

二分查找法每次把搜索区域减少一半,时间复杂度为 O(logn)

三、C语言代码实现

1、递归实现

/*
 * @brief 递归实现二分查找法查找指定元素
 * @param start 需要查找部分的最左边元素的下标
 * @param end 需要查找部分的最右边元素的下标
 * @param key 需要查找的元素
 * @return 成功返回查找到的元素的下标,失败放回FALSE
 */
int binary_search(int* arr1, int start, int end, int key)
{
	if (NULL == arr1)
		return FALSE;

	if (start > end)//递归结束条件
		return FALSE;

	//需要查找部分的中间元素
	int mid = (start + end) / 2; 
	//找到了需要查找的元素
	if (key == arr1[mid])
	{
		return mid;
	}
	//如果比中间元素小,在左半部分继续查找
	else if (key < arr1[mid])
	{
		 return binary_search(arr1, start, mid - 1,key);
	}
	//比中间元素大,在右半部分继续查找
	else
	{
		 return binary_search(arr1, mid + 1, end, key);
	}
}

2、非递归实现

/*
 * @brief 非递归实现二分查找法查找指定元素
 * @param start 需要查找部分的最左边元素的下标
 * @param end 需要查找部分的最右边元素的下标
 * @param key 需要查找的元素
 * @return 成功返回查找到的元素的下标,失败放回FALSE
 */
int binary_search1(int* arr1, int start, int end, int key)
{
	if (NULL == arr1)
		return FALSE;
	while (start <= end)
	{
		//需要查找部分的中间元素
		int mid = (start + end) / 2;
		//找到了需要查找的元素
		if (key == arr1[mid])
		{
			return mid;
		}
		//如果比中间元素大,在右半部分继续查找
		else if (key > arr1[mid])
		{
			start= mid + 1;
		}
		//比中间元素小,在左半部分继续查找
		else
		{
			end = mid - 1;
		}
	}
		return FALSE;
}

3、完整代码

#include<stdio.h>
#include<string.h>
#include <stdbool.h> 

#define TRUE 0
#define FALSE -1

/*
 * @brief 二分查找法查找指定元素
 * @param start 需要查找部分的最左边元素的下标
 * @param end 需要查找部分的最右边元素的下标
 * @param key 需要查找的元素
 * @return 成功返回查找到的元素的下标,失败放回FALSE
 */
int binary_search(int* arr1, int start, int end, int key)
{
	if (NULL == arr1)
		return FALSE;

	if (start > end)//递归结束条件
		return FALSE;

	//需要查找部分的中间元素
	int mid = (start + end) / 2; 
	//找到了需要查找的元素
	if (key == arr1[mid])
	{
		return mid;
	}
	//如果比中间元素小,在左半部分继续查找
	else if (key < arr1[mid])
	{
		 return binary_search(arr1, start, mid - 1,key);
	}
	//比中间元素大,在右半部分继续查找
	else
	{
		 return binary_search(arr1, mid + 1, end, key);
	}
}

/*
 * @brief 二分查找法查找指定元素
 * @param start 需要查找部分的最左边元素的下标
 * @param end 需要查找部分的最右边元素的下标
 * @param key 需要查找的元素
 * @return 成功返回查找到的元素的下标,失败放回FALSE
 */
int binary_search1(int* arr1, int start, int end, int key)
{
	if (NULL == arr1)
		return FALSE;
	while (start <= end)
	{
		//需要查找部分的中间元素
		int mid = (start + end) / 2;
		//找到了需要查找的元素
		if (key == arr1[mid])
		{
			return mid;
		}
		//如果比中间元素大,在右半部分继续查找
		else if (key > arr1[mid])
		{
			start= mid + 1;
		}
		//比中间元素小,在左半部分继续查找
		else
		{
			end = mid - 1;
		}
	}
		return FALSE;
}

int main()
{
	
	int arr1[] = {2,4,6,8,10};

	int ret = binary_search(arr1, 0, sizeof(arr1) / sizeof(arr[0]) - 1, 4);
	printf(" %d\n", ret);

	int ret1 = binary_search1(arr1, 0, sizeof(arr1) / sizeof(arr[0]) - 1, 2);
	printf(" %d\n", ret1);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值