算法设计与分析第2章 递归与分治策略

本文深入探讨了算法设计中的递归与分治策略,包括递归算法的概念、优缺点以及消除递归的方法,通过阶乘、Fibonacci数列、Ackerman函数、全排列问题、整数划分问题、Hanoi塔问题、秦九韶算法等实例进行了详细解释。此外,还介绍了分治法的基本条件、特征,并以二分搜索、合并排序和快速排序为例展示了分治法的应用。
摘要由CSDN通过智能技术生成

第2章 递归与分治策略

2.1 递归算法

递归算法:直接或间接地调用自身的算法。
递归函数:用函数自身给出定义的函数。两个要素:边界条件、递归方程

优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性。
缺点:运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。

解决方法:在递归算法中消除递归调用,使其转化为非递归算法。
1、采用一个用户定义的栈来模拟系统的递归调用工作栈。该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。
2、用递推来实现递归函数。
3、通过变换能将一些递归转化为尾递归,从而迭代求出结果。
后两种方法在时空复杂度上均有较大改善,但其适用范围有限。

例1.阶乘函数

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<stdlib.h>
#include<algorithm>
using namespace std;
long long factorial(long long n)
{
   
    if(n==0) return 1;
    else return n*factorial(n-1);
}
int main()
{
   
    long long  n;
    long long result;
    cout<<"this app compute the factorial of n,please input n:"<<endl;
    while(cin>>n)
    {
   
        result=factorial(n);
        cout<<"The factorial of "<<n<<" is: "<<result<<endl;
    }
    return 0;
}

例2. Fibonacci数列
无穷数列1,1,2,3,5,8,13,21,34,55,……,称为Fibonacci数列。它可以递归地定义为:
在这里插入图片描述

代码:

#include<iostream>
#include<stdlib.h>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int Fibonacci(int n)
{
   
    if(n==0||n==1) return 1;
    else return Fibonacci(n-1)+Fibonacci(n-2);
}
int main()
{
   
    int n,result;
    cout<<"this app compute Fibonacci of n, please input n:"<<endl;
    while(cin>>n)
    {
   
        result=Fibonacci(n);
        cout<<"the Fibonacci of "<<n<<" is :"<<result<<endl;
    }
    return 0;
}

例3 .Ackerman函数
当一个函数及它的一个变量是由函数自身定义时,称这个函数是双递归函数。
Ackerman函数A(n,m)定义如下:
在这里插入图片描述

代码:

#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int Ackerman(int n,int m)
{
   
    if(n==1&&m==0) return 2;
    else if(n==0&&m>=0) return 1;
    else if(n>=2&&m==0) return n+2;
    else if(n>=1&&m>=1) return Ackerman(Ackerman(n-1,m),m-1);
}
int main()
{
   
    int n,m,result;
    cout<<"this app compute the problem of Ackerman,please input n and m:"<<endl;
    while(cin>>n>>m)
    {
   
        result=Ackerman(n,m);
        cout<<"the result is :"<<result<<endl;
    }
    return 0;
}

例4.全排列问题:123 -> 123 132 213 231 312 321</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值