【趣学Python算法100例】折半查找

问题描述

已有一维数组存储了N个预先排序的整数序列。采用二分查找算法以确定整数m在该数组中的位置。如若成功定位到该元素,则需输出其对应的数组下标;若未找到,则反馈信息为"Not found!"。

问题分析

二分查找法,也就是折半查找,它是一种分而治之的策略。想象一下,我们要解决一个大问题,分治算法就是先把这大问题切成几个小块,这些小块互不影响,并且跟原问题一模一样,通过搞定这些小块,最终大问题也就迎刃而解了。二分法呢,就是把问题分成两个小问题来解决的特别方法。

不过,二分查找法有个前提,那就是你得有一个排好序的列表。

具体怎么操作呢?首先,我们得知道要在哪个范围内找。用两个标记,一个叫low,一个叫high,它们就像两条边界线,low在前面,high在后面,表示我们要搜索的这片区域。然后,我们找到这片区域的中间点,标记为mid。接着,拿你要找的数和中间点的数比一比。如果你要找的数更大,那就把前面的low移到mid后面,相当于扔掉前面一半不用看了;反过来,如果你要找的数更小,就把后面的high移到mid前面,也就是忽略后面一半。就这么一减半、一减半地找,直到low和high碰头,表示没地方找了,查找也就结束了。

算法设计

我们有一个按顺序排列好的数字列表,放在了一个数组里。要想找到某个数字在这个列表里的位置,首先我们知道数组的第一个位置是0,而最后一个位置是数组长度N减1,这就是指针low和high最开始时的值,分别是0和N-1。为了找到目标数字,我们不光要用到low、high这两个指针,还要加上一个中间指针mid,以及一个额外的变量k来记录我们正在查看的位置。通过改变k的值,我们就能一步步判断目标数字m是不是在数组里面了。

现在,让我们通过一个简单的图解方式,来理解怎么用"二分查找法"找数字。想象一下数组里这样排着数字:5, 13, 19, 21, 37, 56, 64, 75, 80, 88, 92,我们要找的数字m是21。按照二分查找的规则,一开始,low指针指向数组的第一个数字5,high指针指向最后一个数字92。然后,我们计算中间位置mid,它就是low和high指针位置相加后除以2,这里mid就会指向数字56。下面是一个简化的示意过程:

变量m里面的数字是21,我们要找的指针mid指向的是数字56。因为21比56小,按照二分查找的方法,我们知道接下来只需要在mid指的数字前面这一块找就行了,也就是在数字5到37之间。之前,指针high是指向列表最后一个元素的,但现在它要指向mid前面一个位置,也就是mid-1的位置。然后,我们得重新算一下mid应该指向哪里。简单来说,就是这样的一个过程:

再次进行比较,21大于19,现在比较范围再次转移到mid所指元素的后面,low元素所指元素下标由0变为mid+1。示意如下:

当前mid所指元素的值为21,与要查找的整数值相同,故查找成功,所查元素在表中的序号等于指针mid的值。

完整代码

python 复制代码
def binary_search(arr, target):
    """
    在一个有序的整数列表中执行二分查找,以找到目标值的索引。
    
    参数:
        arr:一个包含整数的已排序列表
        target:要查找的目标整数
        
    返回值:
        如果目标值在列表中找到,则返回其索引;否则返回 -1
    """
    low = 0
    high = len(arr) - 1
    
    while low <= high:
        mid = (low + high) // 2
        if target < arr[mid]:
            high = mid - 1
        elif target > arr[mid]:
            low = mid + 1
        else:
            return mid
    
    return -1

def main():

    # Define the array
    a = [-3, 4, 7, 9, 13, 45, 67, 89, 100, 180]

    # Output the data in the array
    print("a数组中的数据如下:")
    for i in a:
        print(i, end=" ")
    print()

    # Input validation
    while True:
        try:
            m = int(input("Enter m = : "))  # Variable m is the integer to search for
            break
        except ValueError:
            print("请输入一个整数!")

    # Perform binary search
    k = binary_search(a, m)

    # Output result
    if k >= 0:
        print("m = %d, index = %d" % (m, k))
    else:
        print("Not be found!")

if __name__ == "__main__":
    main()

运行结果

在vscode下运行程序,结果下图所示。

相关推荐
wyiyiyi2 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
mit6.8242 小时前
[1Prompt1Story] 滑动窗口机制 | 图像生成管线 | VAE变分自编码器 | UNet去噪神经网络
人工智能·python
没有bug.的程序员2 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
甄超锋2 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
AntBlack3 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
Cx330❀5 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
杜子不疼.5 小时前
《Python学习之字典(一):基础操作与核心用法》
开发语言·python·学习
myzzb6 小时前
基于uiautomation的自动化流程RPA开源开发演示
运维·python·学习·算法·自动化·rpa
TLuoQiu6 小时前
小电视视频内容获取GUI工具
爬虫·python
我叫黑大帅6 小时前
【CustomTkinter】 python可以写前端?😆
后端·python