递归调用

汉诺塔问题(分治递归思想)

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-28 23:02:27
汉诺塔的基本思想就是 1.先把上面n-1个通过c转移到b(因为我的c里面要放n,也就是最大的那个) 2.把a中的 n(最大的那个)移动到c 3.再把b中的n-1个通过a移动到c; 整个过程就结束了,然后递归调用这个函数,每一层递归都执行这三个步骤 最后n=1的时候,想象一下,n=1的时候,是不是把c中的1直接移到c中即可,所以这就是终止条件。今天可算是理解了汉诺塔的原理了!!!` `` #include using namespace std; void movef(int n,char a,char b){ cout<<“把”<<n<<“从”<<a<<“移动到”<<b<<endl; } void haniod(int n,char a,char b,char c){ if(n==1){ movef(n,a,c); }else{ haniod(n-1,a,c,b); movef(n,a,c); haniod(n-1,b,a,c); } } int main(){ int n; cin>>n; haniod(n,‘a’,‘b’,‘c’); } 来源: https://blog.csdn.net/qq_43568790/article/details/100147676

递归与函数调用详细解读

为君一笑 提交于 2019-11-28 21:55:38
草稿箱存不下你了 1、函数的调用 当一个函数运行期间调用另一个函数时,在运行被调函数之前,系统需要完成三件事: 1、将所有的实际参数,返回地址等信息传递给被调函数保存 2、为被调函数的局部变量(也包含形参)分配存储空间 3、将控制权转移到被调函数的入口 从主调函数返回被调函数之前,系统要完成三件事 1、保存被调函数的返回结果 2、释放被调函数所占的存储空间 3、依照被调函数保存的返回地址将控制权转移到主调函数 当有多个函数相互调用时,按照 后调先返回 的原则,上述函数之间信息传递和控制转移必须借助 栈 来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中,每当调用一个函数时,就在栈顶分配一个存储区,进行压栈操作,每当一个函数退出时,就释放它的存储区,就进行出栈操作,使运行的函数永远都在栈顶位置, 伪代码分析; # include <stdio.h> void fun ( ) { 语句A ; g ( ) ; 语句B ; } void g ( ) { 语句c; } int main ( ) { fun ( ) ; return 0 ; } 分析; # include <stdio.h> # include <stdlib.h> void f ( ) ; void g ( ) ; void k ( ) ; void f ( ) { printf ( "ffffff\n" ) ; g

递归的理解

断了今生、忘了曾经 提交于 2019-11-28 19:44:01
递归算法概念是函数调用自己来实现的某种功能,按以下方法理解递归你会恍然大悟(如果你对递归有疑惑的话),并觉得递归是如此简单: 1.递归是高中数学中的数列那一章讲的内容。数列这章讲了一个概念叫递推公式:如果已知数列的第1项(或前几 项),且从第二项(或某一项)开始的任一An与它的前一项An-1(或前几项)间的关系可以用一个公式来表 示,那么这个公式就叫递推公式,递推公式是给出数列的一种方法。 2.例如斐波那契数列的递推公式就是:An=An-1+An-2(n>2,a1=1,a2=1) 3.那么现在如果想用递归的方式表示斐波那契数列即可定义函数f(n):当n>2时f(n)=f(n-1)+f(n-2);当n=1时f(n)=1,当n=2时f(n)=1; 即private static int fibonacciRe(int i) { if(i == 1 || i == 2) return 1; else if(i>2) return fibonacciRe(i-1)+fibonacciRe(i-2); else return 0; } 4.解释:其实说白了递归函数就是一个递推公式,只要递推公式往纸上一写,把项A替换成函数名字,把n替换成函的 参数即可,最后用if处理一下特殊参数值时的结果值就欧了。 5.总结:我们为什么有些人很难理解递归函数呢

递归练习题

久未见 提交于 2019-11-28 18:17:25
不死神兔 package com.liushuaishuai; /* 不死神兔递归 */ public class DiGuiDemo { public static void main(String[] args) { System.out.println(f(20)); } public static int f(int n) { if (n == 1 || n == 2) { return 1; } else { return f(n - 1) + f(n-2); } } } 求阶乘 package com.liushuaishuai; public class DiGuiDemo02 { public static void main(String[] args) { System.out.println(Factorial(4)); } public static int Factorial(int n) { if (n == 1) { return 1; } else { return n * Factorial(n - 1); } } } 遍历目录 package com.liushuaishuai; import java.io.File; public class DiGuiDemo03 { public static void main(String[]

少用,尽量不用递归

风格不统一 提交于 2019-11-28 17:55:39
递归说到底,就是自己调用自己,是一种无穷迭代思维方式,简单粗暴的罗列。 递归对程序员的修养要求极高,无穷递归、栈溢出,各种问题,安全性比较难把握。 来段快排递归: #include <iostream> #include <windows.h> using namespace std; template<class T> void quick_sort(T a[], int low, int high) { int first = low; int last = high; int key = a[first]; if(low >= high) return; while(first < last) { while(first < last && a[last] >= key)last--; a[first] = a[last]; while(first < last && a[first] <= key)first++; a[last] = a[first]; } a[first] = key; quick_sort(a, low, first - 1); quick_sort(a, first + 1, high); } #define CONST_ARRAY_SIZE (3000) int main() { SYSTEMTIME sys_time_start, sys

迭代是人,递归是神(迭代与递归的总结:比较)

陌路散爱 提交于 2019-11-28 17:46:08
版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/lg1259156776/。 https://blog.csdn.net/LG1259156776/article/details/46849809 在计算机编程实现中有常常两种方法:一曰迭代(iterate);二曰递归(recursion)。 从“编程之美”的角度看,可以借用一句非常经典的话: “迭代是人,递归是神!” 来从宏观上对二者进行把握。 从概念上讲,递归就是指程序调用自身的编程思想,即一个函数调用本身;迭代是利用已知的变量值,根据递推公式不断演进得到变量新值得编程思想。 从直观上讲,递归是将大问题化为相同结构的小问题,从待求解的问题出发,一直分解到已经已知答案的最小问题为止,然后再逐级返回, 从而得到大问题的解(一个非常形象的例子就是分类回归树 classification and regression tree,从root出发,先将root分解为另一个(root,sub-tree),就这样一直分解,直到遇到leafs后逐层返回);而迭代则是从已知值出发,通过递推式,不断更新变量新值,一直到能够解决要求的问题为止。 以斐波那契数列的求解为例,通过两种典型的实现进行对比: fib(0)=0; fib(1)=1; fib(n)=fib(n-1)+fib(n-2); 递归的实现 [objc]

为什么你学不会递归?告别递归,谈谈我的一些经验

Deadly 提交于 2019-11-28 17:45:03
可能很多人在大一的时候,就已经接触了递归了,不过,我敢保证很多人初学者刚开始接触递归的时候,是一脸懵逼的,我当初也是,给我的感觉就是,递归太神奇了! 可能也有一大部分人知道递归,也能看的懂递归,但在实际做题过程中,却不知道怎么使用,有时候还容易被递归给搞晕。也有好几个人来问我有没有快速掌握递归的捷径啊。说实话,哪来那么多捷径啊,不过,我还是想写一篇文章,谈谈我的一些经验,或许,能够给你带来一些帮助。 为了兼顾初学者,我会从最简单的题讲起! 递归的三大要素 第一要素:明确你这个函数想要干什么 对于递归,我觉得很重要的一个事就是, 这个函数的功能是什么 ,他要完成什么样的一件事,而这个,是完全由你自己来定义的。也就是说,我们先不管函数里面的代码什么,而是要先明白,你这个函数是要用来干什么。 例如,我定义了一个函数 1// 算 n 的阶乘(假设n不为0)2int f(int n){34} // 算 n 的阶乘(假设n不为0) 2 int f ( int n) { 3 4 } 这个函数的功能是算 n 的阶乘。好了,我们已经定义了一个函数,并且定义了它的功能是什么,接下来我们看第二要素。 第二要素:寻找递归结束条件 所谓递归,就是会在函数内部代码中,调用这个函数本身,所以,我们必须要找出 递归的结束条件 ,不然的话,会一直调用自己,进入无底洞。也就是说,我们需要找出 当参数为啥时,递归结束

彻底理解递归,从递归的本质说起!

旧街凉风 提交于 2019-11-28 17:44:23
遍历二叉树,是学习树这种数据结构首先要理解的一种基本操作。比较简单地方式就是用递归去遍历,鉴于递归这种调用方法有一定的特殊性,今天还是想来讲讲怎么去理解递归遍历。本文针对想理解递归的过程的朋友,因为本人在学到这一部分的时候也纠结了很久,其实只要理解了过程,那以后写递归的代码再也不用“心虚”了,因为那个过程是可预测的,可证明的。 递归调用的特殊性在于自己调用自己,给人一种迷茫感,如果是递归调用“一次”,那还相对好理解,比如求阶乘的递归算法, int F(int n) { if(n==0)//递归边界 return 1; return n*F(n-1);//递归公式 } 一层一层调用,知道递归结束条件成立,再一层一层返回;但如果像二叉树是递归调用“两次”,似乎理解起来就不是很容易了。 void preorder(bintree t){ if(t){ printf("%c ",t->data); preorder(t->lchild); preorder(t->rchild); } } 对于一颗如下的二叉树,它的前序遍历顺序该怎么理解呢?我们今天来好好理一遍它的过程。 可以把递归看成是自己调用另一个和自己功能一样,但是函数名不同的函数来理解,或许看得更清楚明白,下面我们来看看这个前序遍历的过程是怎样的。 首先,我们记上面这个函数为F1,表示外层的函数,内层函数表示下一层的函数

LeetCode 刷题笔记——递归与回溯的理解

空扰寡人 提交于 2019-11-28 17:44:11
LeetCode 刷题笔记——递归与回溯的理解 马上就要入职了。在入职之前受师兄点拨,疯狂刷 LeetCode ,整个痛并快乐着的过程中,在算法和数据结构方面受益良多。 在刷题过程中,很快的就遇到了闻名已久的 递归 (Recursive) 。首次遇到递归,是 LeetCode 的第 17 题: Letter Combinations of a Phone Number 。解这道题的时候,虽然之前没有专门学过,但最先就想到了递归的解法,无师自通的把这个题解开了还让我得意了许久~ 不过后来又遇到了第 22 题: Generate Parentheses ,本来以为是一个很简单的,可以无脑用递归解决的问题,直接废了我一个上午…… 后来网上查了一下,它们说要用 回溯 (Backtrack) 的方法理解并解答。一看代码,形式同样也是反复调用函数自身,感觉这和递归并没什么区别啊? 于是多做了几道关于递归和回溯的问题,并在网上找了一些大神们的言论,自己对 递归 和 回溯 进行一些总结如下。 参考地址: 题库: LeetCode 递归与回溯的区别解释: 《关于递归与回溯比较通俗的方法》 《回溯和递归区别》 答题思路与源码 《leetcode 46. Permutations-全排列|回溯|递归|非递归》 《刷题笔记3(关于Permutation需要知道的事)》 《以Generate

实验四、递归下降语法分析实验

有些话、适合烂在心里 提交于 2019-11-28 17:13:14
实验目的 ( 1 )掌握自上而下语法分析的要求与特点。 ( 2 )掌握递归下降语法分析的基本原理和方法。 ( 3 )掌握相应数据结构的设计方法。 实验内容和要求 编程实现给定算术表达式的递归下降分析器。 算术表达式文法如下: E-->E+T|T T-->T*F|F F-->(E)|i 实验方法、步骤及结果测试 原理分析及流程图 ( 1 )当遇到终结符 a 时,则编写语句 If( 当前读到的输入符号 ==a) 读入下一个输入符号 ( 2 )当遇到非终结符 A 时,则编写语句调用 A() 。 ( 3 )当遇到 A-->ε 规则时,则编写语句 If( 当前读到的输入符号不属于 Follow(A))error() ( 4 )当某个非终结符的规则有多个候选式时,按 LL(1) 文法的条件能唯一地选择一个候选式进行推导 . 主要 程序段及其解释: #include<stdio.h> void E(); void T(); void E1(); void T1(); void F(); char s[100]; int i, SIGN; int main() { printf(" 请输入一个语句 , 以 # 号结束语句 ( 直接输入 # 号推出 ) \n"); while( 1 ) { SIGN = 0; i=0; scanf("%s",&s); if( s[0] == '#') return