《编程简介(Java) ·10.3递归思想》
《编程简介(Java) ·10.3递归思想》
10.3.1 递归的概念
以两种方式的人:男人和女人;算法是两种:递归迭代/通知;
递归方法用自己的较简单的情形定义自己。
在数学和计算机科学中,递归是一种思路和策略,能够用于术语的定义(什么是表达式),问题的描写叙述和问题求解。用于问题求解的递归称为递归法。
有一个故事。物理学家计算10!时会说。“看,它等于1*2*~*10,即3628800”;数学家则说:“哦。10的阶乘,它等于10乘以9。”。
递归算法“轻率地”觉得自己的较简单的情形是已知的。既然fact(n-1)是已知的,因而fact(n) 可求。
这样“轻率”对理解递归概念至关重要。递归法不直接解决这个问题,而是将问题变成一个趋向递归出口的问题。使用递归方法须要存在一个基准情形,以避免无限循环(狗追自己的尾巴)。
package algorithm.recursion;
public class RecursionDemo{
/**
* 递归求Fibonacci级数的第n个元素。n基于1的自然数。
*/
public static int fibonacc(int n){
if(n<=1) return n;
else return fibonacc(n-1)+fibonacc(n-2);
} /**
* 迭代求Fibonacci级数的第n个元素。n基于1的自然数。
*/
public static int fibonacc1(int n){
int first , second ,result ;
first =second=result= 1;
for(int i=3;i<=n ;i++){
result = first + second;
first = second;
second =result;
}
return result;
}
}
大多数情况下,迭代法和递归法可以相互转化。
使用递归法有2条实践准则:
1、设计优先。在不论什么情况下都能够採用递归法。简洁而清晰的程序设计优先。某些问题,比如那些须要后退的问题(如找出迷宫的出路、对树的一些操作)。假设不採用递归则非常难解决。
2、效率平衡。
假设递归调用中出现反复性工作,改用循环。对于一般的数值计算,递归法通常不合适。
Java递归方法是通过方法调用栈实现的。在BlueJ中设置断点执行factorial (5),将显示方法调用情况。
它只“轻率地觉得”factorial (4)已知,依此类推。
到factorial (5),眼下没有进行任一乘法计算。方法调用栈中有6个栈帧,顶层将计算factorial (0)。递归的方法的两个阶段是递推和回归。
比如使用递归式sum(n) =n + sum(n-1),yqj2065看见过一个趣题。
static long sum1(long a) {
return (a == 1)? 1:(a + sum1(a - 1));
}
static long sum2(long a) {
return (a == 1)? 1:(sum2(a - 1) + a);
}
两者有差别吗?【注:在Java7时sum1(6000)StackOverflowError,Java8到大约13000才溢出。原因不明。】
10.3.2 汉诺塔
汉诺塔问题(Hanoi Tower problem):有三根杆子A、B、C,A杆上串有上小下大若干碟子。
每次移动一块碟子。在确保小碟子仅仅能叠在大碟子上面的条件下,利用B过渡,请把全部碟子从A杆移到C杆上。
对于具有递归思维的人。再多的碟子,也只是是两部分:上面的n-1个碟子被看成粘在一起的小碟子,而以下是一个大碟子。汉诺塔问题的递归算法:
结束条件: A杆上仅仅有一个碟子。将它移到C。
递归式:
1、将上面的n-1个碟子从出发地A移到中转站B;
2、将第n个碟子移到目的地C;
3、将n-1个碟子从中转站B移到目的地C。
package algorithm.recursion;
public class HanoiTower{
private static int step= 0;
/**汉诺塔的递归演示。
* @param from 碟子的出发地
* @param temp 碟子的中转站
* @param to 碟子的到达地
* @param n 要移动的碟子个数
*/
static void hanoi(char from, char temp, char to, int n){
if (n == 1) {
step++;
System.out.println("第"+step+ "步: "+ from+"→"+ to);
}else {
//将n-1个碟子移到中转站。故眼下的到达地是temp。
hanoi(from, to,temp,n-1);
//第n个碟子移到到达地
step++;
System.out.println("第"+step+ "步: "+ from+"→"+ to);
//将n-1个碟子移到到达地。
hanoi(temp,from,to,n-1);
}
}
}
hanoi(‘A’, ‘B’, ‘C’, 3)的输出:
第1步: A→C
第2步: A→B
第3步: C→B
第4步: A→C
第5步: B→A
第6步: B→C
第7步: A→C
汉诺塔问题的迭代算法比較复杂,代码库中有參考实现。
练习:
1.Given a non-negative int n, return the sum of its digits recursively (no loops). Note that mod (%) by 10 yields the rightmost digit (126 % 10 is 6), while divide (/) by 10 removes the rightmost digit (126 / 10 is 12).
sumDigits(126) → 9
sumDigits(49) → 13
sumDigits(12) → 3
类似的: 递归求一个非负int包括的5的个数。
2.小朋友排排坐,单号伸出2手指,双号伸出3手指,递归求n个小朋友时手指的总数。
sum(0) → 0
sum(1) → 2
sum(2) → 5
版权声明:本文博主原创文章,博客,未经同意不得转载。
《编程简介(Java) ·10.3递归思想》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- UVA 10828 - Back to Kernighan-Ritchie(概率+高斯消元)
UVA 10828 - Back to Kernighan-Ritchie 题目链接 题意:给图一个流程图,有结点的流程,每次进入下一个流程概率是均等的,有q次询问,求出每次询问结点的运行期望 思路: ...
- hdu3622(二分+two-sat)
传送门:Bomb Game 题意:给n对炸弹可以放置的位置(每个位置为一个二维平面上的点),每次放置炸弹是时只能选择这一对中的其中一个点,每个炸弹爆炸的范围半径都一样,控制爆炸的半径使得所有的爆炸范围 ...
- Matlab---串口操作---数据採集篇
matlab功能强大,串口操作也非常easy.相信看过下面两个实验你就能掌握咯! 開始吧! 实验1: 从电脑COM2口读取数据.并将数据保存在TXT文件里,方便数据分析,以下是M脚本: %名 称:Ma ...
- Linux下安装Python3.3.0
Linux下安装Python3.3.0_路易_新浪博客 Linux下安装Python3.3.0 (2013-01-08 11:45:37)
- [置顶] Firefox OS 学习——manifest.webapp结构分析
在Firefox OS 学习——Gaia 编译分析 这篇文章多次提到manifest.webapp文件,对于做过android app 开发的人来说,都很熟悉Android.mk 和Manifest ...
- android中file的使用实例
File是android的4种存储方式的一种.File就是文件的意思一个文件,你无非是想进行读写操作.所以这就用到两个流.一个数输入流,一个是输出流.FileOutstream,和FileInputS ...
- Filter基金会
一个.总结 简单的说,Filter的作用就是拦截(Tomcat的)service(Request,Response)方法.拿到Request.Response对象进行处理.然后释放控制.继续自己主动流 ...
- c#代码规范和质量检查工具这点事
c#代码规范和质量检查工具这点事 代码风格检查:StyleCop 代码缺陷检查:FxCop 代码质量: 代码度量值/Code Metrics StyleCop 介绍 The StyleCop tool ...
- 彻底理解Javascript原型继承
彻底理解Javascript原型继承 之前写过一篇Javascript继承主题的文章,这篇文章作为一篇读书笔记,分析的不够深入. 本文试图进一步思考,争取彻底理解Javascript继承原理 实例成员 ...
- CentOS7 编译安装LNMP
(文章来自:http://www.cnblogs.com/i-it/p/3841840.html,请各位到这个网址去看原文的) LNMP(Linux-Nginx-Mysql-PHP),本文在CentO ...