递归与分治

参考博文链接

首先需要知道的是:
递归是算法的实现方式,分治是算法的设计思想。
迭代是不断地循环过程,递归是不断地调用自身。

递归

  • 直接或间接调用自身的算法。
  • 用函数自身给出定义的函数称为递归函数。
  • 分治法产生的子问题往往是原问题的较小末世,这就是为使用递归技术提供了方便。原问题与子问题的唯一区别就是输入的规模不同。

递归的弊端就是会不断的消耗内存中的栈空间,并且有相关的值拷贝动作,函数不断压栈,导致资源不断消耗。

分治的过程

  1. 先将规模变小
  2. 递归处理小规模问题
  3. 将小规模问题合并为原始的问题的解

需要注意的是:

  • 分解的条件要互斥,
  • 分解后所有的条件加在一起,能够覆盖原始问题的所有情况

实例

1.阶乘函数
递归定义:
在这里插入图片描述
代码实现:

//阶乘
#include<iostream>
using namespace std;
//递归算法
int factorial_recursive(int n){
    if(n==1)return 1;
    return n*factorial_recursive(n-1);
}
//一般算法
int factorial_loop(int n){
    int res=1;
    for(int i=n;i>0;i--){
        res*=i;
    }
    return res;
}
int main(){
    int n;
    cout<<"输入阶乘的n值:";
    cin>>n;
    cout<<"使用递归算法:\n";
    cout<<n<<"! = "<<factorial_recursive(n)<<endl;
    cout<<"使用一般算法:\n";
    cout<<n<<"! = "<<factorial_loop(n)<<endl;
    return 0;
}

2.斐波那契数列

递归定义:
在这里插入图片描述
代码实现:

//斐波那契数列
#include<iostream>
using namespace std;
//递归
int fibonacci_recursive(int n){
    if(n==0 || n==1){
        return 1;
    }
    return fibonacci_recursive(n-1)+fibonacci_recursive(n-2);
}
//一般算法
int fibonacci_loop(int n){
    if(n==0 || n==1){
        return 1;
    }
    int res1=1;
    int res2=1;
    int res=0;
    for(int i=1;i<n;i++){
        res=res1+res2;
        res1=res2;
        res2=res;
    }
    return res;
}
int main(){
    cout<<"你想要输出多少个斐波那契数列里的值:";
    int n;
    cin>>n;
    //递归算法
    cout<<"fibonacci implement by recursive:\n";
    for(int i=0;i<n;i++){
        cout<<fibonacci_recursive(i)<<" ";
    }
    cout<<endl;
    //一般算法
    cout<<"fibonacci implement by loop:\n";
    for(int i=0;i<n;i++){
        cout<<fibonacci_loop(i)<<" ";
    }
    cout<<endl;
}

3.Ackerman函数
当一个函数及它的一个变量是由函数自身定义时,称这个函数是双递归函数:
递归定义:
在这里插入图片描述
代码:

#include <iostream>
using namespace std;

long ackerman(long n, long m){
    if (n == 1 && m == 0)
        return (long)2;
    if (n == 0 && m >= 0)
        return 1;
    if (m == 0 && n >= 2)
        return n + 2;
    if (n >= 1 && m>= 1)
        return ackerman( ackerman(n-1,m) , m-1);
}

int main()
{
    cout << "m = 0 : " << endl;
    cout << "ackerman(1,0) = " << ackerman(1,0) << endl;
    cout << "ackerman(2,0) = " << ackerman(2,0) << endl;
    cout << "ackerman(3,0) = " << ackerman(3,0) << endl;
    cout << "ackerman(4,0) = " << ackerman(4,0) << endl;

    cout << "m = 1 : " << endl;
    cout << "ackerman(1,1) = " << ackerman(1,1) << endl;
    cout << "ackerman(2,1) = " << ackerman(2,1) << endl;
    cout << "ackerman(3,1) = " << ackerman(3,1) << endl;
    cout << "ackerman(4,1) = " << ackerman(4,1) << endl;

    cout << "m = 2 : " << endl;
    cout << "ackerman(1,2) = " << ackerman(1,2) << endl;
    cout << "ackerman(2,2) = " << ackerman(2,2) << endl;
    cout << "ackerman(3,2) = " << ackerman(3,2) << endl;
    cout << "ackerman(4,2) = " << ackerman(4,2) << endl;

    cout << "m = 3 : " << endl;
    cout << "ackerman(1,3) = " << ackerman(1,3) << endl;
    cout << "ackerman(2,3) = " << ackerman(2,3) << endl;
    cout << "ackerman(3,3) = " << ackerman(3,3) << endl;
    cout << "ackerman(4,3) = " << ackerman(4,3) << endl;

    return 0;
}

4.排列问题
将数列全排列:
n=1时:只有一种排列;
n>1时:将

#include<iostream>
using namespace std;

void perm_recursion(int list[],int k,int m){
    if(k==m){
        for(int i=0;i<=m;i++)
            cout<<list[i]<<" ";
        cout<<endl;
    }
    else{
        for(int i=k;i<=m;i++){
            swap(list[k],list[i]);
            perm_recursion(list,k+1,m);
            swap(list[k],list[i]);
        }
    }
}

int main(){
    int list[]={0,1,2};
    cout<<"permutation implement by recursion:"<<endl;
    perm_recursion(list,0,2);
    cout<<endl;
    return 0;
}

5.整数划分问题
将正整数n表示为一系列正整数的和。不同的划分个数称为n的划分数,记作p(n),
在正整数n的所有不同划分中,将最大加数n1不大于m的划分个数记作q(n,m)。
正整数n的划分数p(n) = q(n,n)
在这里插入图片描述
代码实现:

#include<iostream>
using namespace std;

int q(int n ,int m){
    if(n<1||m<1)
        return 0;
    if(n==1||m==1)
        return 1;
    if(n<m)
        return q(n,n);
    if(n==m)
        return 1+q(n,m-1);
    return q(n,m-1)+q(n-m,m);
}
int p(int n){
    return q(n,n);
}
int main(){
    for(int i=1;i<7;i++){
        cout<<"interger_partition("
        <<i<<") ="<<p(i)<<endl;
    }
    return 0;
}

6.汉诺塔问题
hanoi(n, a, b, c)表示按照游戏规则,n块圆盘从a塔移至b塔,c塔作为辅助塔。

move(a, b)表示将塔a最上面的圆盘移至塔b,并输出这一步骤。
代码实现:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值