递归算法

递归

给你一囗甜甜゛ 提交于 2019-12-02 17:00:57
递推:像上边递归实现所拆解,递归每一次都是基于上一次进行下一次的执行,这叫递推 回溯:则是在遇到终止条件,则从最后往回返一级一级的把值返回来,这叫回溯 什么是递归? 1.递归用一种通俗的话来说就是自己调用自己,但是需要分解它的参数, 2.让它解决一个更小一点的问题,当问题小到一定规模的时候, 3.需要一个递归出口返回。 1.递归必须包含一个基本的出口(base case), 否则就会无限递归,最终导致栈溢出。 比如这里就是n==0返回1 2.递归必须包含一个可以分解的问题(recursive case). 要想求得fact(n),就需要用 n*fact(n-1) 3.递归必须要向着递归出口靠近(toward the base case). 这里每次递归调用都会n-1,向着递归出口n==0靠近 注意: 1.递归算法解题通常显得很简洁,但递归算法解题的运行效率较低,所以一般不提倡用递归算法设计程序。 2.在递归调用的过程中系统为每一层的返回点、局部量等开辟了栈来存储,递归次数过多容易造成栈溢出等。 多个参数的递归示例: 斐波那契数列:就是前两个数的和为后一个数的值(0,1,1,2,3,5,8,13.........) def foo(arg1,arg2,stop): if arg1 == 0: print(arg1,arg2) arg3 = arg1 + arg2 print(arg1

什么是php递归

感情迁移 提交于 2019-12-02 16:38:38
程序调用自身的编程技巧称为递归( recursion) 。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。 递归,就是在运行的过程中调用自己。 构成递归需具备的条件:   函数嵌套调用过程示例    1. 子问题须与原始问题为同样的事,且更为简单;    2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。   在数学和计算机科学中,递归指由一种(或多种)简单的基本情况定义的一类对象或方法,并规定其他所有情况都能被还原为其基本情况。   例如,下列为某人祖先的递归定义:   某人的双亲是他的祖先(基本情况)。某人祖先的双亲同样是某人的祖先(递归步骤)。斐波纳契数列(Fibonacci Sequence),又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21..... I [1] 斐波纳契数列是典型的递归案例:   递归关系就是实体自己和自己建立关系。    Fib(0) = 1

《Python编程从0到1》笔记5——图解递归你肯定看完就能懂!

时光总嘲笑我的痴心妄想 提交于 2019-12-02 15:12:21
本小节的示例比较简单,因为在每次递归过程中原问题仅缩减为单个更小的问题。这样的问题往往能够用简单循环解决。这类递归算法的函数调用图是链状结构。这种递归类型被称为“单重递归”(single recursion)。 示例一:编写函数seq(n),打印从1到n的数字。 可以很容易地用循环解决这个问题: def seq(n): i = 1 while i<=n: print(i) i += 1 也可以使用递归版本,这是本节的主要程序风格: def seq(n): if n>0: seq(n-1) print(n) 在递归版本的seq()函数中,参数等于0时函数什么也不做直接返回。当参数为正整数时[1],将参数减1后调用自身,待调用返回后打印参数。当调用seq(3)时,该函数会生成如下的调用链seq(3) > seq(2) > seq(1) > seq(0),当调用链依次返回时,seq(3) - seq(1)的print语句会逆序执行,完成打印序列的目的。如图 2.10所示。 图 2.10 seq函数的递归调用次序 图 2.11 seq的调用栈变化示意图 在实际编写代码时,不会使用这样的方式打印序列[2]。因为对于本问题来说,递归版本的效率很低。本小节示例的目的是让读者了解递归函数的执行流程和基本语法形式。 [1] 为了简单起见,假定函数只会接收到非负整数作为参数。 [2]

八皇后,回溯与递归(Python实现)

柔情痞子 提交于 2019-12-02 15:05:08
八皇后,回溯与递归(Python实现) 八皇后问题是十九世纪著名的数学家高斯1850年提出 。以下为python语言的八皇后代码,摘自《Python基础教程》,代码相对于其他语言,来得短小且一次性可以打印出92种结果。同时可以扩展为九皇后,十皇后问题。 问题:在一个 8*8 棋盘上,每一行放置一个皇后旗子,且它们不冲突。冲突定义:同一列不能有两个皇后,每一个对角线也不能有两个皇后。当然,三个皇后也是不行的,四个也是不行的,凭你的智商应该可以理解吧。 解决方案:回溯与递归。 介绍: 1.回溯法 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。参见 百度百科 2.递归法 阶乘 n! = 1 x 2 x 3 x ... x n 用函数 fact(n) 表示,可以看出: fact(1) = 1 fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n 于是, fact(n) 用递归的方式写出来就是: def fact(n): if n==1: return 1 return n * fact(n - 1) 如果计算 fact(5) ,结果如下: ==

ACM算法笔记

▼魔方 西西 提交于 2019-12-02 12:32:18
HNU君陌 此笔记为本人在准备ACM校赛时阅读资料所整理的总结心得,适合入门级的同学,仅供参考: 第一部分语言 第一章程序设计入门 1.1算术表达式 整数型用printf()时为%d,实数用%f输出,保留一位n数为printf(“%.nf”, ) 1.2变量及其输入 整数型用scanf()时为%d,实数用%lf输入,%5d表示按5位数打印,%05d表示按5位数表示,不足补0。 占位符和变量的数据类型一一对应,且每个变量前均需要加”&”符号。 竞赛时,选手程序的执行是自动完成的,没有人工干预,不需要界面友好。也不要让程序按任意键退出:system(“pause”)或添加一个多余的getchar() 不要在竞赛中使用getch()、getche()、gotoxy()、clracr()函数 在算法竞赛中,每行输出均应以回车符结束,包括最后一行,除非特别说明,每行的行首不应有空格,但行末可以有多余空格。另外,输出的每两个数或者字符串之间应以单个空格隔开。即算法竞赛的程序制作三件事:读入数据,计算结果,打印输出 1.3变量交换 三变量法: t=a; a=b; b=t; 单变量法(只有定义了加减法的数据类型才可以): a=a+b; b=a-b; a=a-b; 1.4分支结构程序设计 第二章循环结构设计 2.1 for循环 尽量缩短变量的定义范围。 浮点运算可能存在误差,在进行浮点数比较的时候

第二模块 3.8 函数的递归

我们两清 提交于 2019-12-02 12:26:10
举例: 求100不断除以2直到商为0为止,打印每次除的商 n = 100 while n >0: n = int(n/2) print(n) 用递归函数表示: def calc(n): n = int(n/2) print(n) if n >0: calc(n) calc(100) 如果一个函数在内部调用自已本身,这个函数就叫做递归函数。上面我们写的这个代码就是递归 def calc(n): n = int(n/2) print(n) if n >0: calc(n) print(n) calc(100) 递归特性: 必须有一个明确的结束条件 每次进入更深一层递归时,问题规模相比上次递归都应有所减少 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出) 练习题 用递归实现2分查找的算法,以从列表 a = [1,3,4,6,7,8,9,11,15,17,19,21,22,25,29,33,38,69,107] 查找指定的值。 a = [1,3,4,6,7,8,9,11,15,17,19,21,22,25,29,33,38,69,107] def binary_search(start, end, n

《剑指offer》树专题 (牛客10.25)

╄→尐↘猪︶ㄣ 提交于 2019-12-02 11:40:54
考察的知识点主要在于树的数据结构(BST,AVL)、遍历方式(前序,中序,后序,层次)、遍历算法(DFS,BFS,回溯)以及遍历时借助的数据结构如队列和栈。由于树本身就是一个递归定义的结构,所以在递归求解问题时,要善于将问题转化成合适的子问题,思考清楚子问题的形式、递归的出口、父问题与子问题的联系。 以下这些问题难度都不太大,很多都是一次过,比上次链表专题的思维难度小多了。 难度 题目 知识点 04. 重建二叉树 依据前序和中序遍历重建 , 递归 ★★ 17. 树的子结构 递归 18. 二叉树的镜像 简单递归 22. 从上往下打印二叉树 bfs , Queue的使用 23. 判断是否为二叉搜索树的后序遍历序列 BST , 递归 ★ 24. 二叉树中和为某一值的路径 dfs , 回溯 , Collections.sort() ★★ 26. 二叉搜索树与双向链表 递归 中序遍历 ★ 38. 二叉树的深度 递归 39. 平衡二叉树 平衡二叉树 递归 57. 二叉树的下一个结点 中序遍历 循环 回溯后的情况 58. 对称的二叉树 递归 可转化为非递归 59. 按之字形顺序打印二叉树 Stack 层次遍历变形 60. 把二叉树打印成多行 Queue LinkedList 层次遍历 ★★ 61. 序列化二叉树 递归 string.split() string.equals 62.

数据结构与算法应用

喜欢而已 提交于 2019-12-02 10:50:44
16.1 数据结构与算法应用基础 算法灵活度高,不容易拿分,拿部分分6-8分就不错啦 16.2 分治法 往往运用递归解决问题 16.3 分治法(递归技术):必须掌握,不然很多问题难以理解 递归:就是函数在运行的过程中调用自己 为什么调用自己:我们要解决的问题可以才分为多个同类型的子问题,既然函数是用来解决这个复杂问题的,那么函数也可以解决子问题,所以自己调自己。 16.4 分治法具体应用(二分查找) 16.5 回溯法--深度优先 解决经典的迷宫问题 16.6 贪心法(性价比) 每一步都选择最好的东西所以叫贪心法 特色:在短时间找出解,但不一定是最优解 16.7 动态规划法(在逻辑方面非常复杂) 分治法与动态的区别: 动:子问题的解与原问题可能有关联,将子问题的解存在一个表中 动态规划法会构造出一个表去 查表 16.8 数据结构与算法应用分析1 解题思路:先解决其他方面的问题,再解决代码问题,有促进作用 16.9 案例2 来源: https://blog.csdn.net/shujuku____/article/details/102752858

汉诺塔问题递归与非递归算法

ぃ、小莉子 提交于 2019-12-02 07:06:27
汉诺塔问题递归与非递归算法 汉诺塔问题描述如下: 有 A、B、C 3 根针,n 个圆盘(从 1..n )从上到下,按小到大顺序放在 A 处,要求每次移动一个,并保持从小到大的叠放顺序, 利用 C,把 n 个盘子移动到 B 处。 递归算法 递归算法比较容易理解 fn hanoi(n): hanoi_move(n, 'A', 'B', 'C') fn hanoi_move(n, from, to, medium): if n <= 0: return hanoi_move(n-1, 'A', 'C', 'B') println("move {} from {} to {}", n, from, to); hanoi_move(n-1, 'C', 'B', 'A') 非递归算法 重新思考整个移动过程,在处理 n 从 A 到 B 时,需要先处理其上的 n-1 个圆盘从 A 到 C,直到 A 处只剩下 1 个编号为 n 的圆盘,这个步骤定义为 Step : struct Step { n, r, from, to, medium } r 表示当前编号为 n 其上面还放着有多少个圆盘,当 r 为 1 时,就可以移动编号为 n 的圆盘了,即: Step(n, r, from, to, medium) 分解为 1. Step(r-1, r-1, from, medium, to) 2. Step

使用递归计算给定数组元素的总和

此生再无相见时 提交于 2019-12-02 06:31:56
计算给定数组 arr 中所有元素的总和,转载自CSDN博客网 1.不考虑算法复杂度,用递归做:   function sum(arr) {    var len = arr.length;    if (len == 0){    return 0;    } else if (len == 1){    return arr[0];    } else {    return arr[0] + sum(arr.slice(1));    }   } 2.常规循环:   function sum(arr) {    var s = 0;    for ( var i=arr.length-1; i>=0; i--) {    s += arr[i];    }    return s;   } 3.函数式编程 map-reduce:   function sum(arr) {    return arr.reduce( function (prev, curr, idx, arr){    return prev + curr;    });   } 4.forEach遍历:   function sum(arr) {    var s = 0;    arr.forEach( function (val, idx, arr) {    s += val;    }, 0);