递归算法

2020-12-04  本文已影响0人  清风烈酒2157

[toc]

递归

一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的。用递归过程定义的函数,称为递归函数,例如连加、连乘及阶乘等。凡是递归的函数,都是可计算的,即能行的

首先你要理解函数调用的本质:

保存当前指令地址
跳转到被调用函数(指令段)的起始地址实际过程比这个复杂, 比如还包括保存临时变量和传参等等, 但是对我们正在讨论的问题不起到本质影响所以省略掉不谈
函数调用并不是在原地展开代码
每一个函数都是一段独立存在于存储器中的指令序列
每个程序的内存空间中都包括一个叫做"栈(stack)"的区域, 它的特点是先进后出, 就像一摞书, 只能往顶端放书, 也只能从顶端取书每当你调用一次函数, 就会向栈中压入(push)返回地址, 当函数返回(return)时从栈中弹出(pop)返回地址并跳转回返回地址.
所以, 自身调用乃至循环调用形成的递归调用在进行时, 就会不断压栈来保存函数运行状态, 当递归一层一层返回时, 则是不断出栈了函数调用并不是在原地展开代码

单次调用递归

函数:
void func(int N){
    N++;
    if (N>2){
        return;
    }else{
        printf("%d\n",N);
        func(N);

    }
}
调用:
func(0);

打印

1
2

分析 :

栈有几个 这里会走几次,表示正在出栈


4e1859f1fc53386049ad2821fbf9130d
void func(int N){
    N++;
    if (N>2){
        return;
    }else{
        func(N);
        printf("%d\n",N);
    }
}

打印

2
1

分析:

void func(int N){
    N++;
    if (N>2){
        return;
    }else{
        func(N);
    }
    
     printf("%d\n",N);
}

打印

2
1

分析,和示例二一样

两次调用递归

void func(int N){
    N++;
    if (N>2){
        return;
    }else{
        printf("%d\n",N);
        func(N);
        func(N);
    }
    
}
1
2
2

分析

void func(int N){
    N++;
    if (N>2){
        return;
    }else{
        func(N);
        printf("%d\n",N);
        func(N);
    }
    
}
2
1
2

分析

最后这个执行两次分别是下面函数N=2时不满足出栈,和之前要出栈有执行打印和函数的那个N=1出栈.


160bc11cf1b39933297afdacc25fd5ea
void func(int N){
    N++;
    if (N>2){
        return;
    }else{
        func(N);
        func(N);
        printf("%d\n",N);
    }
}

2
2
1

参考

原来连续两次递归调用很简单

上一篇 下一篇

猜你喜欢

热点阅读