重温二分查找与尾递归

本文探讨了二分查找算法及其尾递归实现方式,对比了普通递归与尾递归的不同之处,并通过代码实例展示了如何利用尾递归来优化递归调用,减少堆栈空间的消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 问题来源:“递归”这个洪水猛兽

“递归”越深,占用的“堆栈”空间越大,如果使用“递归”实现“二分查找”,堆栈空间以 l o g 2 N log_2{N} log2N的形式增长,这就太尴尬了!然而,“递归”这种程序设计模式方便人类阅读,那么有没有什么办法解决这个“堆栈空间占用过巨”的问题呢?

答:可以使用“尾递归

尾递归和普通递归的区别在于:是否让函数返回值参与运算!
如果使用尾递归,就不要返回值传参,可以把要返回的值通过函数的“参数列表”传递

2 代码

2.1 循环体实现二分查找

int BinarySearch(int target, int *arr, int len)
{
    int start = 0;
    int end = len - 1;

    while(start <= end){
        int mid = (start + end) / 2;
        if(arr[mid] == target){
            return mid;
        }else if(target < arr[mid]){
            end = mid - 1;
        }else{
            start = mid + 1;
        }
    }

    return -1;
}

2.2 尾递归实现二分查找

int recursion_BinarySearch(int target, int *arr, int start, int end)
{
    if(start > end){ // Termination conditions
        return -1;
    }else{
        int mid = (start + end) >> 1;
        if(target == arr[mid]){
            return mid;
        }else if(target < arr[mid]){
            end = mid - 1;
        }else{
            start = mid + 1;
        }
        return recursion_BinarySearch(target, arr, start, end);
    }
}

3 性能测试

测试用例

int arr[] = {1, 6, 9, 21, 100, 155, 165, 243, 255};
int main(int argc, char *argv[])
{
    int target = 165;
    int index = -1;
    index = recursion_BinarySearch(target, arr, 0, sizeof(arr)/sizeof(int)-1);
    if(index > -1){
        printf("%d is founded. Index = %d\r\n", target, index);
    }else{
        printf("%d is not founded!\r\n", target);
    }
    return 0;
}

3.1 普通递归(GCC默认-O1)

在这里插入图片描述

3.2 尾递归(GCC 开启-O2及以上优化)

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值