关于二分查找(C#及C++实现)

本文详细探讨了二分查找的实现方式,包括递归和迭代两种方法,并解答了关于选择、优化和效率的问题。文章通过数学归纳法和循环不变式证明了二分查找的正确性,并给出了C++的支持和实践建议,鼓励读者通过比较不同二分查找的运行时间来加深理解。
摘要由CSDN通过智能技术生成

二分查找

不同的二分查找

用递归实现的二分查找
static int BinarySearch<T>(IList<T> list, T target)
    where T : IComparable<T>
{
   
    return BinarySearch(list, 0, list.Count - 1, target);
}
static int BinarySearch<T>(IList<T> list, int low, int high, T target)
    where T : IComparable<T>
{
   
	if (low > high)
        return -1;
    int mid = (high - low) / 2 + low;
    int comp = list[mid].CompareTo(target);
    if (comp == 0)
        return mid;
    if (comp < 0)
        return BinarySearch(list, mid + 1, high, target);
    else
        return BinarySearch(list, low, mid - 1, target);
}
用迭代实现的二分查找
public static int BinarySearch<T>(IList<T> list, T target)
    where T : IComparable<T>
{
   
    int low = 0, high = list.Count - 1;
    while (low <= high) {
   
        int mid = (high - low) / 2 + low;
        int comp = list[mid].CompareTo(target);
        if (comp == 0)
            return mid;
        if (comp < 0)
            low = mid + 1;
        else
            high = mid - 1;
    }
    return -1;
}
一些疑惑
  • 为什么要使用comp保存CompareTo的结果?
    T来说,CompareTo的开销可能较大,用comp保存结果可以减少一次比较
  • 为什么要用(high - low) / 2 + low而非(high + low) / 2
    (high + low) / 2有溢出的风险,而经过计算我们可以发现(high - low) / 2 + low恒等于(high + low) / 2
  • 为什么使用[low, high](闭区间)作为范围?
    这是便于理解的需要,选用[low, high]或是[low, high)取决于你会不会访问list[high]
一些问题
  • 如果有多个target存在于list中,那么返回哪一个是不确定的
    我们希望返回第一个或返回最后一个
  • 如果target不存在于list中,只返回-1
    毋宁说,如果target寻找失败,就返回一个负数,那么我们为什么不让这个负数携带更多信息
    最常见的是返回的这个负数k,有list[n less than ~k] < target < list[n greater than ~k]~k代表按位取反~k总非负),即返回tar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值