【趣学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下运行程序,结果下图所示。

相关推荐
u0109147605 小时前
CSS组件库如何快速扩展_通过Sass @extend继承基础布局
jvm·数据库·python
baidu_340998825 小时前
Golang怎么用go-noescape优化性能_Golang如何使用编译器指令控制逃逸分析行为【进阶】
jvm·数据库·python
m0_678485455 小时前
如何利用虚拟 DOM 实现无痕刷新?基于 VNode 对比的状态保持技巧
jvm·数据库·python
qq_342295825 小时前
CSS如何实现透明背景效果_通过RGBA色彩模式控制透明度
jvm·数据库·python
TechWayfarer5 小时前
知乎/微博的IP属地显示为什么偶尔错误?用IP归属地查询平台自检工具3步验证
网络·python·网络协议·tcp/ip·网络安全
Greyson16 小时前
CSS如何处理超长文本换行问题_结合word-wrap属性
jvm·数据库·python
justjinji6 小时前
如何批量更新SQL数据表_使用UPDATE JOIN语法提升效率
jvm·数据库·python
小江的记录本6 小时前
【网络安全】《网络安全常见攻击与防御》(附:《六大攻击核心特性横向对比表》)
java·网络·人工智能·后端·python·安全·web安全
贵沫末6 小时前
python——打包自己的库并安装
开发语言·windows·python
weixin_580614006 小时前
MySQL存储过程中如何防止SQL注入_使用参数化查询规范
jvm·数据库·python