剑指offer-递归和循环

本文对比了递归与循环在实现斐波那契数列、数值整数次方计算及矩阵顺时针打印等常见算法问题上的优劣。通过具体案例分析了递归的简洁性和潜在的时间与空间开销,并提供了优化方案。

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

递归虽然比较简洁,但他同时也有显著的缺点。递归由于是函数调用自身,而函数调用是有时间和空间的消耗的,每一次函数调用都需要在内存栈中分配空间以保存参数、返回地址及临时变量,而且往栈里压入数据和弹出数据都需要时间。
1、 斐波那契数列 0,1,1,2,3,5,8,13 …

//递归      缺陷:重复计算的太多
int  Fib(int n){
    if(n==0)
            return 0;
    if(n==1)
            return 1;
    return Fib(n-1)+Fib(n-2);
}
//循环
int Fib(int n){
    if(n==0)   return 0;
    if(n==1)   return 1;
    int fib0=0;
    int fib1=1;
    int fibsum=0;
    while(n>=2){
        fibsum=fib0+fib1;
        fib0=fib1;
        fib1=fibsum;
        n--;
    }
    return fibsum;
}

//尾递归:当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,覆盖当前的活动记录而不是在栈中去创建一个新的
int Fib(int n,int a,int b)
{
    return   n==0?a:Fib(n-1,b,a+b);
}

2、数值的整数次方

double Power(double base,int exponent)
{
    if(exponent==0)
            return 1;
    int flag=1;
    if(exponent<0)    flag=-1;      
    int e=abs(exponent);
    int s=1;
    while(e>0){
        s*=base;
        e--;
    }
    if(flag)
        return s;
    else 
        return 1/s;
}

//代码改善   在上面的代码中可以看到,如果指数是32,则在while循环内部需要进行31次乘法。可以再16次的基础上再乘以一次就可以了,即使用公式
//a^n=a^(n/2)*a^(n/2)           偶数 
//a^n=a^(n-1/2)*a^(n-1/2)*a     奇数
int Power(double base,int exponent){
    if(exponent==0)
                return 1;
    if(exponent==1)
                return base;
    double result=Power(base,exponent>>1);
    result*=result;
    if(exponent&0x01==1)
        result*=base;       
    return result;
}

3、顺时针打印矩阵

// 1  2  3  4
// 5  6  7  8
// 9 10 11 12
//13 14 15 16
//将上述4*4的数组按顺时针打印:1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10
void PrintByClock(int (*a)[4], int rows, int columns){
    int start = 0;
    while (start * 2<columns&&start * 2<rows){
        //1.打印start行,不包含最后一个
        int i = start;
        for (; i<columns-start; i++)
            cout << a[start][i] << " ";
        //2.打印i列,不包含最后一个
        int j = start;
        for (; j<rows-start; j++)
            cout << a[j][i] << " ";
        //3.打印j行,不包含最后一个
        int k = columns-start;
        for (; k>start; k--)
            cout << a[j][k] << " ";
        //4.打印start列
        int m = rows-start;
        for (; m>start; m--)
            cout << a[m][start] << " ";
        start++;
        cout<<"start:"<<start<<endl;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值