递归思路

需求:计算1*2*3*....*1000的值

常规代码:

def func(arg):
    res = 1
    for i in range(1, arg):
         res *= i
    return res

递归方法:

def fun(arg):
    if arg == 1:
        return 1
    return arg*(fun(arg-1))
  • 通过此函数发现,函数最终return的是函数本身的表达式,如果计算5以内的阶乘,他的运行如下:
  1. fun(5)调用函数fun()函数,此时arg = 5,5>1,所以会return 5 * fun(4)
  2. fun(4)会调用fun()函数,此时arg=4,4>1,所以会return 4 * fun(3)
  3. fun(3)会调用fun()函数,此时arg=3,3>1,所以会return 3 * fun(2)
  4. fun(2)会调用fun()函数,此时arg=2,2>1,所以会return 2 * fun(1)
  5. fun(1)会调用fun()函数,此时arg=1,1=1,所以会return 1
  6. 当fun(1)将值返回给fun(2)之后,此时fun(2)=fun(1)*2=2,继续往上返回给fun(3)
  7. 当fun(2)将值返回给fun(3)之后,此时fun(3)=fun(2)*3=6,继续往上返回给fun(4)
  8. 当fun(3)将值返回给fun(4)之后,此时fun(4)=fun(3)*4=24,继续往上返回给fun(5)
  9. 当fun(4)将值返回给fun(5)之后,此时fun(5)=fun(4)*5=120,最终得出结果
  • 创建递归的条件
  1. 一个基线条件:递归终止的条件,需递归开始的时候进行判断处理。
  2. 一系列的规则:使对递归函数的每次调用都趋进于直至达到这个基线条件

递归可以提高代码的可读性,但是运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。

原文地址:https://www.cnblogs.com/dyuan8888/p/11930080.html

时间: 2024-08-12 02:14:29

递归思路的相关文章

汉诺塔问题递归与非递归思路

//递归解法,复杂度为O(2^n)//T(n) = 2(n-1) + 1//T(1) = 1#include <iostream> using namespace std; void hanoi(int n, char a, char b, char c) { if (n==1) cout << n << " " << a << " " << c << endl; else { ha

用两种递归思路与循环实现单链表的反转

typedef struct ListNode{ int data; struct ListNode *next; }ListNode; //递归一 ListNode *ReverseList (ListNode *pHead, ListNode *nHead = NULL) { //每次取下第一个节点头插法创建新链表 //nHead为反转后链表的头节点 if(pHead == NULL) return NULL; ListNode *pNext = pHead -> next; pHead -

我的递归思路。

算法可以说是计算机里的数学,也可以描述成带有计算机特点的数学.我把递归视为一种特别的函数.用数学的思想来思考递归更加明晰快速. 看一个经常见到的例子,累加1+2+3+4+···········+n. 数学表达式为: 代码形式为: public  int Sum(int n) {     if(n==1) {return 1;}     else {return n+Sum(n-1);} } 这是我们常见的形式,递归出口为: n>1.递归体为: f(n-1)+n.这是一个出口,思考一下,数值为1,

约瑟夫环(猴子问题)递归思路解法

“约瑟夫环”是一个数学的应用问题:一群猴子排成一圈,按1,2,…,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数, 再数到第m只,在把它踢出去…,如此不停的进行下去, 直到最后只剩下一只猴子为止,那只猴子就叫做大王.要求编程模拟此过程,输入max.size, 输出最后那个大王的编号. 对于这个问题,可以这么解:每次有猴子出列后,就给所有猴子重新编号:首先第一个出列的猴子编号NO1=(size % max)==0 ? max : (size % max)(作判断是因为si

递归思路简单例子

var a = 0; function fun(i) { a++; console.log(a); fun(i+1); console.log("end"); } fun(0); //调用自己 运行结果如下,陷入死循环,永远不会执行console.log("end")直至程序报错 给了条件之后 ,当条件满足然后他就开始返回 var a = 0; function fun(i) { if(i >50) {//不给条件的话他会一直陷入死循环直至程序报错 retur

八皇后问题,递归法实现

八皇后问题,是19世纪著名的数学家高斯在1850年提出的:在8×8格的国际象棋盘上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列.同一斜线上,试问有多少种摆法?高斯先生给出的答案是“76”种,实际是76种吗? 八皇后问题是回溯算法的典型应用,但是本文提供递归的求法. 递归的核心思想可以总结成:把一个复杂的问题无限缩小,每个小问题的解法都是一样的,最终归结于求解每个小问题的原型.递归编程的思路可以假设所有的问题都已解决,来到结束条件,这是非常简单的,然后再调用自身求解整个问

POJ-1163-The Triangle: DP入门 递归 递推

递归思路 超时算法 #include<iostream> using namespace std; #define Size 101 int Triangle[Size][Size]; int n; int GetAns( int i, int j ) { if( i==n ) return Triangle[i][j]; int x=GetAns( i+1, j ); int y=GetAns( i+1, j+1 ); return max(x, y)+Triangle[i][j]; } i

递归入门 Java

对于强大的递归.要想做到灵活运用,是需要花时间进行练习并总结.往往递归学习的入门也是难度也比较大,常常会处于看得明,却写不出的"尴尬"情况. 递归的定义 将一个大的问题分解成比较小的.有着相同形式的问题. 递归是一种强有力的思想.在计算机科学的学习中,一个重要的必须学习的概念是递归.递归是一种编程策略,它把一个大的问题分解成具有相同形式的简单问题. 使用递归的必需条件 可以通过递归调用来缩小问题规模,且新问题与原问题有着相同的形式 存在一种简单情境,可以使递归在简单情境下退出 一般对递

C语言强化(十一)二叉树镜像变化 | 要求:不使用递归

用了这么久的递归,现在不让用递归了,你行么? 通过这道题,你可以学会 如何镜像变化一棵二叉树 什么是递归的本质 如何巧妙地使用辅助栈 题目: 输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点. 要求: 不使用递归 例如输入: 输出: 将二叉树镜像变化的方法很简单,只要把所有节点的左右节点对调就行了,使用递归可以非常容易的实现. 如下为递归方法实现镜像变化的函数 /** 二叉树镜像变化--递归方法实现 */ void Revertsetree_R