二分查找(代码实例)

基本思路

当我们要从一个序列中查找一个元素的时候,最快想到的方法就是顺序查找法(即:从前到后依次查找)。但这种方法过于无脑,就是暴力的把每个元素都排查一遍。元素个数少的时候还行,一旦元素个数多起来,效率是非常低下,所以在实际中这种查找的方法是被摒弃的。

这里就不得不介绍一种简单且效率较高的查找方法了:二分查找法,又称折半查找法。但该方法是建立在有序的前提下的,基本思路就是:
先找到那个有序序列的中间元素mid,然后拿它和要找的元素K进行比较,就可以初步判断元素K所在范围,既然查找范围已确定,自然该范围之外的元素就可以不用再查找了(你看这样相较于顺序查找一下子就可以省略一半的元素不用查找了,这就是效率啊!)。当然接下来还会按照上面的步骤反复查找下去。
因为二分查找每一次查找都可以缩减掉一半的查找范围,由此可以知道二分查找法的时间复杂度是: log ⁡ 2 ( N ) 。举个例子来解释该时间复杂度:若这里一共有2^32个元素,那么我在最坏的情况下也只需要32次就可以找到我想找的元素;而顺序查找法最坏的情况下,却需要查找 4,294,967,296‬ 次!!!,可见二分查找法的效率是非常之高的。

前提条件

都说二分查找法的前提条件是:查找的序列必须是有序的。我想大概很多小伙伴都会错误的认为有序是差值恒为1的顺序数列(就像这样1、2、3、4、5、6、7、8、9)。这只不过是有序的某一种情况罢了,那何为有序呢?即该序列中的所有元素都是按照升序或者降序排列好的,元素与元素只间的差值虽然是随机的,但始终是在递增或递减。
除此之外,二分查找只能实现单值查找,不可能实现多值查找!

时间复杂度

时间复杂度指出了算法有多快。例如,假设列表包含n个元素。简单查找需要检查每个元素,因此需要执行n次操作。使用时间复杂度,这个运行时间为O(n)。单位秒呢?没有——时间复杂度指的并非以秒为单位的速度。时间复杂度让你能够比较操作数,它指出了算法运行时间的增速。
二分查找的时间复杂度如图所示:在这里插入图片描述
下面介绍一些常见算法的时间复杂度:
O(log n),也叫对数时间,这样的算法包括二分查找。
O(n),也叫线性时间,这样的算法包括简单查找。
O(n * logn),这样的算法包括第4章将介绍的快速排序——一种速度较快的排序算法。
O(n2 ),这样的算法包括第2章将介绍的选择排序——一种速度较慢的排序算法。
O(n!),这样的算法包括接下来将介绍的旅行商问题的解决方案——一种慢的算法。
在这里插入图片描述

代码实例

C语言实现

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//存储递增的有序数列
	int sz = sizeof(arr) / sizeof(arr[0]);//sz是数组元素的总个数
	int mid = 0;//存储中间元素的下标

	//左、右元素下标确定了被查找元素k的所在范围
	int left = 0;//最左边元素的下标
	int right = sz - 1;//最右边元素的下标
	int k = 0;//所要查找的元素k
	printf("请输入所要查找的数:");
	scanf("%d", &k);

	while (left <= right)
	{
		mid = (left + right) / 2;//计算中间元素的下标
	//判断mid和看大小,重新精确k所在范围
		if (arr[mid] < k)
		{
			left = mid + 1;
			//如果中间的数字小于目标值,则中间数字向左的所有数字都小于目标值,全部排除
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
			//如果中间的数字大于目标值,则中间数字向右的所有数字都大于目标值,全部排除
		}
		else
		{
			break;
		}
	}
	if (left > right)
		printf("没有找到该数\n");
	else
	{
		printf("找到了\n");
	}
}

Python实现

nums = [-2,3,4,5,6,9]

def er_search_(alist,item):
    left,right=0, len(alist)-1
    while left<=right:
        mid = (left+right)//2
        if alist[mid] < item:
            left = mid + 1
        elif alist[mid] > item:
            right = mid - 1
        else:
            return mid
    return -1

er_search_(nums,6)

4
er_search_(nums,9)
5

LeetCode算法题

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。

示例:
输入: nums = [1,3,5,6], target = 5
输出: 2

int searchInsert(int* nums, int numsSize, int target){
   int l=0, r= numsSize-1;
   int ans = numsSize;
   while(l <= r){
       int mid = (l+r)/2;
       if(nums[mid] >= target){
           ans = mid;
           r = mid - 1;
       }
       else {
           l = mid +1;
       }
   }
   return ans;
}
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二分查找是一种快速查找的方法,它可以在有序数组中查找指定元素的位置。首先,我们需要对数组进行初始化,即确定左右指针的初始位置。然后,利用二分法的思想,将待查找的元素与数组的中间元素进行比较。如果中间元素小于等于待查找元素,则将左指针移动到中间元素的位置。如果中间元素大于待查找元素,则将右指针移动到中间元素的位置。重复以上步骤,直到找到目标元素或者左指针等于右指针。 在Python中实现二分查找可以按照以下步骤进行: 1. 初始化左右指针为数组的边界值,即左指针为-1,右指针为数组长度。 2. 当左指针加1不等于右指针时,执行以下循环。 3. 计算中间位置m,通过将左指针与右指针之和除以2得到。 4. 若中间元素小于等于待查找元素,则将左指针移动到中间位置。 5. 若中间元素大于待查找元素,则将右指针移动到中间位置。 6. 返回右指针所在位置的元素,即为目标元素。 这是用Python实现二分查找的示例代码: ```python def binary_search(arr, key): N = len(arr) l, r = -1, N # 初始化左右指针的位置 while l + 1 != r: # 当左指针加1不等于右指针时执行循环 m = int(l + (r - l) / 2) # 计算中间位置m if arr[m <= key: # 若中间元素小于等于待查找元素 l = m # 将左指针移动到中间位置 else: r = m # 若中间元素大于待查找元素,则将右指针移动到中间位置 return arr[r # 返回右指针所在位置的元素 if __name__ == '__main__': arr = [1, 2, 3, 4, 5, 5, 5, 8, 9] key = 5 num = binary_search(arr, key) print(num) ``` 以上是关于二分查找的边界问题的Python实现方法。通过对左右指针的初始化和移动,我们可以在有序数组中快速查找指定元素的位置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [二分查找 边界查找](https://blog.csdn.net/CCSUXWZ/article/details/120771067)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Python有序查找算法之二分法实例分析](https://download.csdn.net/download/weixin_38627769/13774169)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值