描述
递归(recursion):程序调用自身的编程技巧。

递归满足2个条件:
1)有反复执行的过程(调用自身)
2)有跳出反复执行过程的条件(递归出口)

递归与栈的关系
下面演示的是求n的阶乘

int Factorial(int n){
if (n == 0) return 1;
return n * Factorial(n - 1);
}

常常听到 “递归的过程就是出入栈的过程”,这句话怎么理解?我们以上述代码为例,取 n=3,则过程如下:

第 1~4 步,都是入栈过程,Factorial(3)调用了Factorial(2),Factorial(2)又接着调用Factorial(1),直到Factorial(0);

第 5 步,因 0 是递归结束条件,故不再入栈,此时栈高度为 4,即为我们平时所说的递归深度;

第 6~9 步,Factorial(0)做完,出栈,而Factorial(0)做完意味着Factorial(1)也做完,同样进行出栈,重复下去,直到所有的都出栈完毕,递归结束。

每一个递归程序都可以把它改写为非递归版本。我们只需利用栈,通过入栈和出栈两个操作就可以模拟递归的过程,二叉树的遍历无疑是这方面的代表。

但是并不是每个递归程序都是那么容易被改写为非递归的。某些递归程序比较复杂,其入栈和出栈非常繁琐,给编码带来了很大难度,而且易读性极差,所以条件允许的情况下,推荐使用递归。

示例题目
1.有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少对?请使用递归和非递归实现。

import java.util.Scanner;

public class Main{
/*
* 兔子的规律为数列1,1,2,3,5,8,13,21.... 这是一个菲波拉契数列问题 {斐波拉契数列原理:除开前两项 后面每位数等于前两项相加之和}
* 1.通过中间值来保存上一月兔子的和 2.在将上一月兔子这一月兔子相加 得到下一月数量和
*/ // 非递归
public static void f1(int month) {
int rabbit = 1; // 上月兔子的数量和
int newRabbit = 1; // 这一月生成兔子的数量和
int count; // 中间值 用来存数量的
if (month == 1) {
System.out.println("第1月兔子 1 对");
} else if (month == 2) {
System.out.println("第2月兔子 1 对");
} else {
// 从第三月起
for (int i = 3; i <= month; i++) {
count = newRabbit;
newRabbit = rabbit + newRabbit;
rabbit = count;
}
System.out.println("第" + month + "月兔子 " + newRabbit + " 对");
}
} // 递归
public static int f2(int month) {
if (month == 1 || month == 2) {
return 1;
}
// 上一个月的兔子数
int rabbit1 = f2(month - 1);
// 上一个月的前一个月兔子数
int rabbit2 = f2(month - 2);
return rabbit1 + rabbit2;
} public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int month = sc.nextInt();
f1(month);
System.out.println("============");
System.out.println("第" + month + "月兔子 " + f2(month) + " 对");
}
}

2.十进制转二进制

import java.util.Scanner;

/*
* 十进制转二进制
*/
public class Main {
// 非递归
public static void f1(int n) {
int t = 0;
int bin = 0;
int r = 0;
while (n != 0) {
r = n % 2;
n = n / 2;
bin += r * Math.pow(10, t);
t++;
}
System.out.println(bin);
} // 递归
public static void f2(int n) {
if (n / 2 == 0) {
System.out.print(n % 2);
} else {
f2(n / 2);
System.out.print(n % 2);
} } public static void main(String[] args) {
System.out.println("请输入一个非负的十进制整数:");
Scanner sc = new Scanner(System.in);
int number = sc.nextInt();
if (number < 0) {
System.out.println("不符合要求");
} else {
System.out.print("对应的二进制:");
f1(number);
System.out.println("=================");
System.out.print("对应的二进制:");
f2(number);
}
}
}

Java算法——递归思想的更多相关文章

  1. Python算法——递归思想

    编程语言在构建程序时的基本操作有:内置数据类型操作.选择.循环.函数调用等,递归实际属于函数调用的一种特殊情况(函数调用自身),其数学基础是数学归纳法.递归在计算机程序设计中非常重要,是许多高级算法实 ...

  2. 《编程简介(Java) &#183;10.3递归思想》

    <编程简介(Java) ·10.3递归思想> 10.3.1 递归的概念 以两种方式的人:男人和女人:算法是两种:递归迭代/通知: 递归方法用自己的较简单的情形定义自己. 在数学和计算机科学 ...

  3. JAVA算法系列 快速排序

    java算法系列之排序 手写快排 首先说一下什么是快排,比冒泡效率要高,快排的基本思路是首先找到一个基准元素,比如数组中最左边的那个位置,作为基准元素key,之后在最左边和最右边设立两个哨兵,i 和 ...

  4. java算法之超级丑数

    问题描述: 写一个程序来找第 n 个超级丑数. 超级丑数的定义是正整数并且所有的质数因子都在所给定的一个大小为 k 的质数集合内. 比如给你 4 个质数的集合 [2, 7, 13, 19], 那么 [ ...

  5. Java 之递归删除目录

    Java 之递归删除目录 一.思想 必须从最里层的文件开始删除,使用递归删除. 二.源代码:RecursiveDeleteDirectory.java package cn.com.zfc.day01 ...

  6. Java中递归的优缺点,Java写一个递归遍历目录下面的所有文件包括子文件夹里边的文件。

    题目: 遍历出aaa文件夹下的文件 首先分析思路: 1.首先判断这个文件夹是否为文件,通过isFile()函数可以判断是否为文件. 2.然后通过isDirectory判断是否为目录. 3.如果是目录就 ...

  7. [剑指Offer]48-最长不含重复字符的子字符串(递归思想,循环实现)

    题意 如题,字符串只含a-z,输出该子串长度.例:"arabcacfr",输出4. 解题思路 递归思想 计f(i)为以第i个字符结尾的最长不含重复字符的子串长度. 状态转移:计d为 ...

  8. 算法 递归 迭代 动态规划 斐波那契数列 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. Java实现递归将嵌套Map里的字段名由驼峰转为下划线

    摘要: 使用Java语言递归地将Map里的字段名由驼峰转下划线.通过此例可以学习如何递归地解析任意嵌套的List-Map容器结构. 难度:初级 概述 在进行多语言混合编程时,由于编程规范的不同, 有时 ...

随机推荐

  1. 第四章 常用API(下)

    4.1.String类 描述:该类代表字符串 构造方法: 方法 描述 public String() 初始化构造一个空白字符串 public String(char[] value) 通过字符数组初始 ...

  2. Python List min()方法

    描述 min() 方法返回列表元素中的最小值.高佣联盟 www.cgewang.com 语法 min()方法语法: min(list) 参数 list -- 要返回最小值的列表. 返回值 返回列表元素 ...

  3. Skill 扫描list中是否含有某元素

    https://www.cnblogs.com/yeungchie/ code procedure(ycInListp(scan keylist) prog((times) times = 0 for ...

  4. luogu P4769 [NOI2018]冒泡排序 结论 树状数组 卡特兰数

    LINK:冒泡排序 神题. 可以想到爆搜 期望得分5~10分. 打成这个样子心态不得爆炸? 仔细分析 一个不合法序列还有什么标志. 容易想到某个数字离自己位置相反的方向多走了一步. 考虑单独对每个数字 ...

  5. Python代码规范性检测

    一定要注重代码规范,按照平时的代码管理,可以将Python代码规范检测分为两种: 静态本地检测:可以借助静态检查工具,比如:Flake8,Pylint等,调研了一下,用Flake8的相对较多,功能满足 ...

  6. 实践录丨如何在鲲鹏服务器OpenEuler操作系统中快速部署OpenGauss数据库

    本文适合需要快速了解OpenGauss基本使用和操作的单机用户,可以短时间内完成安装体验.对于企业级生产使用或者需要部署多台服务器的,不适合本文. 因为业务需要,要在鲲鹏架构里安装单机版的OpenGa ...

  7. layui 父页面获取弹窗传递的值 和 父页面传值给子弹窗的方法

    1.父页面获取子页面(弹窗)的值: 现在父页面页面加载方法中定义方法,专门用来获取从子页面的值 $(document).ready(function() { //拿到子窗口中传回的数据 functio ...

  8. charles抓取HTTPS设置,详细踩坑版

    写这篇文章的背景就是,每次我在一台新电脑上用charles抓包时,总是因为各种原因无法抓到https请求,每个百度出来的回答又不是那么详细,需要通过几篇回答才能解决过程中的各种问题,所以把自己的安装经 ...

  9. python 调用百度接口 做人脸识别

    操作步骤差不多,记得要在百度AIPI中的控制台中创建对应的工单 创建工单成功后 会生成两个key  这个两个key是要生成tokn 用 这里大家可以用 def函数 将token返回 供下面的接口使用 ...

  10. [vue] computed 和 method

    计算属性 计算属性只有在它的相关依赖发生改变时才会重新取值 Method method每次渲染的时候都会被执行 举一个栗子 <template>...<div>  <p& ...