递归

递归构造二叉树和二叉树的遍历

时光总嘲笑我的痴心妄想 提交于 2020-02-25 19:25:01
学习递归构造二叉树,并且进行前序遍历。 前序遍历,中序遍历和后序遍历是什么? 遍历的顺序分别如下: 前序遍历: 根节点 ,左子树,右子树; 中序遍历:左子树, 根节点 ,右子树; 后序遍历:左子树,右子树, 根节点 。 明眼人可能看出来了:这里的前中后指的是 根节点的位置 。 前序遍历是根节点在前,中序遍历指根节点在中间遍历,中序遍历又叫做“投影遍历”,顺序基本上没变。 递归生成树的代码: //定义 结点结构体 struct tnode { T data ; tnode < T > * left ; tnode < T > * right ; tnode < T > * parent ; } ; //递归生成树的函数 //返回指向根节点的指针 double alpha ; //根节点的比例 template < typename iterator > //迭代器类型 iterator tree_generation ( iterator start , size_t n ) { if ( n < 1 ) return NULL ; size_t c = ( n - 1 ) * alpha ; //根相对位置 iterator root = start + c ; //根节点的位置 iterator left_subtree = tree_generation ( start , c

递归

独自空忆成欢 提交于 2020-02-25 17:19:05
传统的递归思想:自已调用自已,但是调用栈里面的执行上下文会越来越多,容易暴栈。 采用尾递归可以规避这个问题:每次入栈出栈再入栈 尾调用 // 尾调用 function f(x){ return g(x); } // 伪代码 ECStack.push(<f> functionContext); ECStack.pop(); ECStack.push(<g> functionContext); ECStack.pop(); 非尾调用 // 非尾调用 function f(x){ return g(x) + 1; } ECStack.push(<f> functionContext); ECStack.push(<g> functionContext); ECStack.pop(); ECStack.pop(); 示例:阶乘 function factorial(n, res) { if (n == 1) return res; return factorial(n - 1, n * res) } console.log(factorial(4, 1)) // 24 来源: oschina 链接: https://my.oschina.net/u/2285087/blog/3157667

python递归与乘方

假如想象 提交于 2020-02-25 12:58:06
python乘方 a=2**3 print(a) Python递归使用 #求n的阶乘 def factorial(n): if n==1: return 1 else: return n*factorial(n-1) while(1): number=int(input("input an int type number:")) result=factorial(number) print("%d的阶乘为:%d"%(number,result)) 运行结果: 来源: CSDN 作者: zexin2018 链接: https://blog.csdn.net/zexin2018/article/details/104491190

递归算法1

最后都变了- 提交于 2020-02-25 01:15:59
今天学了递归算法,下面的题目是对递归的理解 &1.问第n个学生多大 题目描述 例2.1有n个学生坐在一起 问第n个学生多少岁?他说比第n-1个学生大2岁. 问第n-1个学生岁数,他说比第n-2个学生大2岁. .......................................................... 问第2个学生,说比第1个学生大2岁. 最后问第1个学生,他说是10岁. 请问第n个学生多大? 输入 输入n 输出 输出第n个学生的年龄 样例输入 5 样例输出 18 思路:(关键点为第一个学生的年龄) 第1个学生年龄为10岁(往后每个学生比前一个学生大两岁) n age 1 10 (当n=1时age=10,这个条件要单独列出) 2 age(2-1)+2 3 age(3-1)+2 ... ... n age(n-1)+2 #include<iostream> using namespace std; int fac(int a) { int age; if(a==1){return age=10;} else return fac(a-1)+2; } int main() { int n; cin>>n; cout<<fac(n)<<endl; return 0; } &2.Fibonacci 题目描述 Ø例5.2 求Fibonacci数列问题。

递归函数-汉诺塔经典递归

非 Y 不嫁゛ 提交于 2020-02-25 01:15:06
前言 最近在读《JavaScript语言精粹》,对递归函数有了进一步的认识,希望总结下来: 递归是一种强大的编程技术,他把一个问题分解为一组相似的子问题,每一问题都用一个寻常解去解决。递归函数就是会直接或者间接调用自身的一种函数,一般来说,一个递归函数调用自身去解决它的子问题。 "汉诺塔"经典递归问题 "汉诺塔"是印度的一个古老传说,也是程序设计中的经典的递归问题,是一个著名的益智游戏:   题目如下:     塔上有三根柱子和一套直径各不相同的空心圆盘,开始时源柱子上的所有圆盘都按从大到小的顺序排列。目标是通过每一次移动一个圆盘到另一根柱子上,最终把一堆圆盘移动到目标柱子上,过程中不允许把较大的圆盘放置在较小的圆盘上;      寻找规律(把所有的圆盘移动到C):   1)n(圆盘个数) == 1     第一次:1号盘 A -> C sum(移动次数) = 1   2)n == 2     第一次:1号盘 A -> B     第二次:2号盘 A -> C     第三次:1号盘 B -> C  sum = 3   3)n == 3     第一次:1号盘 A -> C     第二次:2号盘 A -> B     第三次:1号盘 C -> B     第四次:3号盘 A -> C     第五次:1号盘 B -> A     第六次:2号盘 B -> C     第七次

深入理解和设计递归技术的关键点的思考

馋奶兔 提交于 2020-02-25 01:11:42
如何理解递归,写出正确的递归程序,我觉得有几个关键点: 1.要从整体把握问题 递归的难点在于人脑并不适合去跟踪递归中自己调用自己的这个过程,这是因为人脑中不像计算机一样有一个可以记忆的堆栈, 但是不同的是人是会归纳的,而计算机只知道调用-返回。 因此,理解和设计递归,一定要从整体把握,数学归纳法和递归是一个对称的关系,数学归纳法不断的扩展自己,递归则是不断的分解 自己。递归中的递就是把主问题分解成子问题,归就是利用子问题的解逐步向上求解的过程了。 关键点是要善用数学归纳法里面的假设 ,就是假设子问题已经求解了,它得到的结果是什么,一旦这么想就是在从整体上把握问题,不必再去纠结细节。设计一个递归函数的时候,首先像普通函数一样设计一个算法框架,控制好程序逻辑,处理递归调用的时候假设是在调用一个其他的函数,这个函数已经设计好,你只需要知道他做什么事,然后返回什么就可以了,具体怎么做的,不需要去想,这似乎有些矛盾,因为这个函数本来就是自己,怎么不需要去想怎么做的呢?其实这就是递归难以理解的原因。所以必须先把细节放在一边,先确定好框架,然后再去处理细节。 2.关注函数的返回值是什么,如何利用子函数调用的返回值得到调用的返回值。 第一条里面设计好框架以后,然后我们就需要关注函数处理的细节了,这个细节包括流程分支,函数的返回值。 函数的返回值直接关系到函数是否正确执行

深度理解递归技术

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

递归方法整合

天大地大妈咪最大 提交于 2020-02-24 09:40:10
1 /*菜单树下拉,禁止选择当前项及其子项,以防止死循环*/ 2 /*item表示递归树,compID表示比对的需要禁止选择的项ID*/ 3 // 实例:编辑情况下,禁止选择当前节点及其子节点 4 export function diGuiTreeEdit(item, compID) { 5 const dataSor = item 6 let treeAry = [] 7 for (let i in dataSor) { 8 const v = dataSor[i] 9 let node = {} 10 if (v === null || v === undefined) { } 11 else { 12 if (v.children && v.children.length > 0) { 13 if (v.id == compID) { 14 node.isDisabled = true 15 } else { 16 node.isDisabled = false 17 } 18 node.id = v.id 19 node.label = v.label 20 node.name = v.name 21 node.children = diGuiTreeEdit(v.children, compID) 22 treeAry.push(node) 23 } else { 24

数据结构与算法--递归(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)递归 必须向退出递归的条件逼近 ,否则就是无限递归

JAVA专项练习

£可爱£侵袭症+ 提交于 2020-02-23 17:04:28
解析:排序过程就是进行比较和交换过程,而时间复杂度就与比较和交换的次数相关。 解析:二维数组为4*3,可表示为 1 0 0 3 2 0 6 7 8 9 0 0 因为数组的起始位置为a[0][0],所以a[2][1]为第三行第二列,即7。 解析:递归工作栈里面包括返回地址、本层的局部变量和递归调用的形参代换用实参,所以正常情况下,无论递归过程有没有使用局部变量,转换为非递归过程都需要用栈来模拟这个递归调用过程。 不稳定:快选堆希 稳 定:插冒归基 归并排序的平均时间复杂度为O(nlogn), 其他三个排序的平均时间复杂度为O(n^2) 快速排序、归并排序和插入排序必须等到整个排序结束后才能够求出最小的 10 个数,而堆排序只需要在初始堆的基础上再进行 10 次筛选即可,每次筛选的时间复杂度为 O(log2n) 外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。外部排序最常用的算法是多路归并排序,即将原文件分解成多个能够一次性装入内存的部分,分别把每一部分调入内存完成排序。然后,对已经排序的子文件进行多路归并排序。 尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次