递归调用

深度理解递归技术

懵懂的女人 提交于 2020-02-25 01:10:59
递归的使用条件:   存在一个递归调用的终止条件;   每次递归的调用必须越来越靠近这个条件;只有这样递归才会终止,否则是不能使用递归的! 总之,在你使用递归来处理问题之前必须首先考虑使用递归带来的好处是否能补偿   他所带来的代价! 否则,使用迭代算法会比递归算法要高效。 递归的基本原理:   1 每一次函数调用都会有一次返回.当程序流执行到某一级递归的结尾处时,它会转移到前一级递归继续执行.   2 递归函数中,位于递归调用前的语句和各级被调函数具有相同的顺序.如打印语句 #1 位于递归调用语句前,它按照递归调用的顺序被执行了 4 次.   3 每一级的函数调用都有自己的局部变量.   4 递归函数中,位于递归调用语句后的语句的执行顺序和各个被调用函数的顺序相反.    即位于递归函数入口前的语句,右外往里执行;位于递归函数入口后面的语句,由里往外执行。   5 虽然每一级递归有自己的变量,但是函数代码并不会得到复制.   6 递归函数中必须包含可以终止递归调用的语句. 一旦你理解了递归( 理解递归 , 关键是脑中有一幅代码的图片 , 函数执行到递归函数入口时 , 就扩充一段完全一样的代码 , 执行完扩充的代码并 return 后 , 继续执行前一次递归函数中递归函数入口后面的代码 ),阅读递归函数最容易的方法不是纠缠于它的执行过程,而是相信递归函数会顺利完成它的任务

数据结构与算法--递归(recursion)

送分小仙女□ 提交于 2020-02-24 02:02:38
递归的概念 简单的说: 递归就是方法自己调用自己 ,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。 递归调用机制 我列举两个小案例,来帮助大家理解递归 1、打印问题 2、阶乘问题 //输出什么? public static void test(int n) { if (n > 2) { test(n - 1); } System.out.println("n=" + n); } //阶乘 public static int factorial(int n) { if (n == 1) { return 1; } else { return factorial(n - 1) * n; }} 3、使用图解说明递归的调用机制 递归能解决什么样的问题 1、各种数学问题如: 8皇后问题 , 汉诺塔, 阶乘问题, 迷宫问题, 球和篮子的问题(google编程大赛) 2、各种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等. 3、将用栈解决的问题-->第归代码比较简洁 递归需要遵守的重要规则 1)执行一个方法时,就创建一个新的受保护的独立空间(栈空间) 2)方法的局部变量是独立的,不会相互影响, 比如n变量 3)如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据. 4)递归 必须向退出递归的条件逼近 ,否则就是无限递归

57.基础语法-递归函数

▼魔方 西西 提交于 2020-02-22 16:07:33
递归 函数直接或者间接的调用自己 阶乘 def fun0(n): print(n) if n == 1: return 1 else: return n * fun0(n-1) print(fun0(5)) 非彼拉切数列 def fun1(n): if n == 1 or n == 2: return 1 else: return fun1(n-2) + fun1(n-1) x_fun1 = 5 print("斐波拉且数列的第 {h} 个数是 {w}".format(h = x_fun1, w = fun1(x_fun1))) print("斐波拉且数列的第 %d 个数是 %d" % (x_fun1, fun1(x_fun1))) 汉诺塔 def hnt(a, b, c, n): if n == 1: print("{} --> {}".format(a, c)) elif n == 2: print("{} --> {}".format(a, b)) print("{} --> {}".format(a, c)) print("{} --> {}".format(b, c)) else: hnt(a, c, b, n-1) print("{} --> {}".format(a, c)) hnt(b, a, c, n-1) hnt_a = "A" hnt_b = "B" hnt_c

转:一文学会递归解题

独自空忆成欢 提交于 2020-02-22 15:53:40
前言 递归是算法中一种非常重要的思想,应用也很广,小到阶乘,再在工作中用到的比如统计文件夹大小,大到 Google 的 PageRank 算法都能看到,也是面试官很喜欢的考点 最近看了不少递归的文章,收获不小,不过我发现大部分网上的讲递归的文章都不太全面,主要的问题在于解题后大部分都没有给出相应的时间/空间复杂度,而时间/空间复杂度是算法的重要考量!递归算法的时间复杂度普遍比较难(需要用到归纳法等),换句话说,如果能解决递归的算法复杂度,其他算法题题的时间复杂度也基本不在话下。另外,递归算法的时间复杂度不少是不能接受的,如果发现算出的时间复杂度过大,则需要转换思路,看下是否有更好的解法 ,这才是根本目的,不要为了递归而递归! 本文试图从以下几个方面来讲解递归 什么是递归? 递归算法通用解决思路 实战演练(从初级到高阶) 力争让大家对递归的认知能上一个新台阶,特别会对递归的精华:时间复杂度作详细剖析,会给大家总结一套很通用的求解递归时间复杂度的套路,相信你看完肯定会有收获 什么是递归 简单地说,就是如果在函数中存在着调用函数本身的情况,这种现象就叫递归。 以阶乘函数为例,如下, 在 factorial 函数中存在着 factorial(n - 1) 的调用,所以此函数是递归函数 public int factorial ( int n ) { if ( n < = 1 ) {

递归调用转为循环

天大地大妈咪最大 提交于 2020-02-22 05:35:21
背景 有一个接口会返回json格式的字符串,json格式是嵌套的,类似这样的如下的结构,需要转换为一个list,当然最简单的写一个递归就可以了,但是有一句话: “所有的递归都可以转化为循环”,那么就练练自己的代码能力,温故而知新,用循环实现吧。 { "respData" : [ { "id" : 1 , "isvalid" : 1 , "orgName" : "汽车" , "parentId" : 0 , "subOrgList" : [ { "id" : 33 , "isvalid" : 1 , "orgName" : "客车" , "parentId" : 1 , "subOrgList" : [ { "id" : 37 , "isvalid" : 1 , "orgName" : "大客车" , "parentId" : 33 } , { "id" : 38 , "isvalid" : 1 , "orgName" : "小客车" , "parentId" : 33 } ] } , { "id" : 88 , "isvalid" : 1 , "orgName" : "SUV" , "parentId" : 1 } ] } , { "id" : 2 , "isvalid" : 1 , "orgName" : "自行车" , "parentId" : 0 , "subOrgList"

递归

你离开我真会死。 提交于 2020-02-21 17:29:50
一、什么是递归? 递归,就是在运行的过程中调用自己。 递归,需要写出口。    //斐波那契数列指的是这样一个数列:1、1、2、3、5、8、13、21、…… //这个数列从第三项开始,每一项都等于前两项之和。 public static int get(int num) { if (num==1) { return 1; } if (num==2) { return 1; } return get(num-1)+get(num-2); } 来源: https://www.cnblogs.com/l1314/p/12342044.html

Java数据结构与算法->递归

感情迁移 提交于 2020-02-21 11:25:26
递归 递归设计思路 1.找重复 (子问题) 2.找重复中的变化量 -> 参数 3.找参数变化趋势 -> 设计出口 换句话说就是把一个任务划一刀分成两份,自己做一部分,委托别人做另外一部分。 练习策略 1.循环改递归 2.经典递归 3.大量练习,总结规律,掌握套路 递归的定义 1.自身调用自身 public class Main { public static void main ( String [ ] args ) { function ( 10 ) ; } static void function ( int i ) { if ( i == 0 ) { //退出递归的条件 return ; } function ( i - 1 ) ; //自身调用自身 } } 练习 求n*(n-1)的阶乘 public class Main { public static void main ( String [ ] args ) { f1 ( 10 ) ; } /* * f1(n):求n的阶乘 --> 求n-1的阶乘 * 找重复:n*(n-1)的阶乘,求(n-1)是问题的重复 * 找变化:变化的量应该作为参数 * 找边界:出口 */ static int f1 ( int n ) { if ( n == 1 ) { return 1 ; //因为1的阶乘就是1 } return n * f1

基础知识概要

家住魔仙堡 提交于 2020-02-20 19:29:21
1.算法复杂度——O记号,Ω符号,θ符号 T(n)=O(f(n)) iff c>0,当 n足够大时,有T(n)<c*f(n)T(n)=Ω(f(n)) iff c>0,当 n足够大时,有T(n)>c*f(n)T(n)=θ(f(n)) iff c1c2>0,当 n足够大时,有c1*f(n)>T(n)>c2*f(n) 2.复杂度类型 1)常数复杂度——O(1):效率最高 2)对数复杂度——O(logn):lnN,lgN,log,这类算法非常有效,复杂度无限接近于常数,logN=O(N^c) 3)多项式复杂度——O(n^c): 4)线性复杂度——O(n):所有O(n)类函数 5)指数复杂度——O(a^n):这类算法计算成本增长极快,通常被认为不可忍受 3.复杂度分析的主要方法: 迭代:级数求和 递归:递归跟踪+递推方程 猜测+验证 4.封底估算 1天=24hr*60min*60sec=25*4000=10^5sec 一生=一世纪=100yr*365=3*10^4day=3*10^9sec 三生三世=10^10sec 5.迭代和递归 计算任意n个整数之和 迭代:int sum=0;//O(1)for(int i=0;i<n;i++)//O(n) sum+=A[i];O(1) return sum;O(1)递归:return (n<1)?0:sum(A,n-1) +A[n-1]

PHP无限级分类的递归算法

蓝咒 提交于 2020-02-20 19:23:21
至少需要3个字段 第一个是主键(ID),第二个是父级分类ID(parentid),第三个是分类的名称(classname)。可能的一种效果是: ID PARENTID CLASSNAME 1 0 一级分类A 2 0 一级分类B 3 1 二级分类A 4 1 二级分类B 主要思路:首先看第三行和第四行,父类ID(PARENTID)的值是1,表示属于id=1这个类的子类,而,一,二两行因为是一级分类,没有上级分类,所以父类ID(PARENTID)的值是0,表示初级分类,依次类推便实现了无限级分类。最终的效果是: ├一级分类A ├─┴二级分类A ├─┴二级分类B ├一级分类B 然后就是程序,这里以PHP作为描述语言,可以很方便的改成其他语言,因为原理相似,就是一个递归而已。 <?php $dbhost = "localhost"; // 数据库主机名 $dbuser = "root"; // 数据库用户名 $dbpd = "123456"; // 数据库密码 $dbname = "test"; // 数据库名 mysql_connect($dbhost,$dbuser,$dbpd); //连接主机 mysql_select_db($dbname); //选择数据库 mysql_query("SET NAMES 'utf8'"); display_tree("├",0); function

递归和列队

对着背影说爱祢 提交于 2020-02-20 05:53:22
一. 递归函数 # 递归调用:一个函数,调用了自身 称为递归调用 # 递归函数: 一个会调用自身的函数称为递归函数 # 凡是循环能干的事情 递归都能干 # 方式: # 写出临界条件 # 我这一次和上一次的关系 # 假设当前函数已经能用 调用自身计算上一次结果 在求出本次的结果 # 输入一个数(大于等于1) 求 1+2+3.......的和 def sum1(n): sum=0 for x in range(1,n+1): sum+=x return sum res=sum1(5) print(res) def sum2(n): if n==1: return 1 else: return n+sum2(n-1) res=sum2(3) print(res) #3 # 5+sum2(4) # 5+4+sum2(3) # 5+4+3+sum2(2) # 5+4+3++2sum2(1) # 5+4+3+2+1 # 模拟栈数据结构 # 压栈向栈里导入数据 a1=[] a1.append("A") print(a1) #['A'] a1.append("B") print(a1) #['A', 'B'] a1.append("C") print(a1) #['A', 'B', 'C'] # 出栈 b1=a1.pop() print(b1) # C print(a1) # ['A', 'B']