Java算法——递归思想
描述
递归(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算法——递归思想的更多相关文章
- Python算法——递归思想
编程语言在构建程序时的基本操作有:内置数据类型操作.选择.循环.函数调用等,递归实际属于函数调用的一种特殊情况(函数调用自身),其数学基础是数学归纳法.递归在计算机程序设计中非常重要,是许多高级算法实 ...
- 《编程简介(Java) ·10.3递归思想》
<编程简介(Java) ·10.3递归思想> 10.3.1 递归的概念 以两种方式的人:男人和女人:算法是两种:递归迭代/通知: 递归方法用自己的较简单的情形定义自己. 在数学和计算机科学 ...
- JAVA算法系列 快速排序
java算法系列之排序 手写快排 首先说一下什么是快排,比冒泡效率要高,快排的基本思路是首先找到一个基准元素,比如数组中最左边的那个位置,作为基准元素key,之后在最左边和最右边设立两个哨兵,i 和 ...
- java算法之超级丑数
问题描述: 写一个程序来找第 n 个超级丑数. 超级丑数的定义是正整数并且所有的质数因子都在所给定的一个大小为 k 的质数集合内. 比如给你 4 个质数的集合 [2, 7, 13, 19], 那么 [ ...
- Java 之递归删除目录
Java 之递归删除目录 一.思想 必须从最里层的文件开始删除,使用递归删除. 二.源代码:RecursiveDeleteDirectory.java package cn.com.zfc.day01 ...
- Java中递归的优缺点,Java写一个递归遍历目录下面的所有文件包括子文件夹里边的文件。
题目: 遍历出aaa文件夹下的文件 首先分析思路: 1.首先判断这个文件夹是否为文件,通过isFile()函数可以判断是否为文件. 2.然后通过isDirectory判断是否为目录. 3.如果是目录就 ...
- [剑指Offer]48-最长不含重复字符的子字符串(递归思想,循环实现)
题意 如题,字符串只含a-z,输出该子串长度.例:"arabcacfr",输出4. 解题思路 递归思想 计f(i)为以第i个字符结尾的最长不含重复字符的子串长度. 状态转移:计d为 ...
- 算法 递归 迭代 动态规划 斐波那契数列 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Java实现递归将嵌套Map里的字段名由驼峰转为下划线
摘要: 使用Java语言递归地将Map里的字段名由驼峰转下划线.通过此例可以学习如何递归地解析任意嵌套的List-Map容器结构. 难度:初级 概述 在进行多语言混合编程时,由于编程规范的不同, 有时 ...
随机推荐
- LQB20180航班时间(sscanf)
首先找找规律,两者相加除以二. 按格式读入sscanf 按格式输出printf("02d%",m);前导0 #include <iostream> #include & ...
- Day02_Vue.js与Webpack
Vue.js与Webpack 1 vue.js介绍 1.vue.js是什么? Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设 ...
- Python删除元组
Python删除元组: 删除元组中的某一个元素: # 删除元组中的元素 tuple_1 = ('a','b','c','d','e') # 删除第 2 个元素 tuple_1 = tuple_1[:1 ...
- Redis 的 KEYS 命令不能乱用啊
KESY 命令 时间复杂度: O(N) , 假设Redis中的键名和给定的模式的长度有限的情况下,N为数据库中key的个数. Redis Keys 命令用于查找所有符合给定模式 pattern 的 k ...
- JDK8的Optional用法
参考资料:https://www.baeldung.com/java-optional https://mp.weixin.qq.com/s/P2kb4fswb4MHfb0Vut_kZg 1. 描述 ...
- Mybatis 的连接池技术
我们在前面的 WEB 课程中也学习过类似的连接池技术,而在 Mybatis 中也有连接池技术,但是它采用的是自 己的连接池技术.在 Mybatis 的 SqlMapConfig.xml 配置文件中,通 ...
- Windows系统护眼色设置
Win10&Win8系统设置护眼色1. windows+R键调出运行窗口(或者鼠标右击开始键,选择运行)2. 在运行窗口中输入 regedit 调出注册表编辑器3. 按照如下顺序找到windo ...
- JavaScript动画实例:炸开的小球
1.炸开的小球 定义一个小球对象类Ball,它有6个属性:圆心坐标(x,y).小球半径radius.填充颜色color.圆心坐标水平方向的变化量speedX.圆心坐标垂直方向的变化量speedY. B ...
- python2.2 elif多条件判断
#案例:存款大于100万,买宝马:大于50万买丰田:大于20万买二手车:小于20万自行车! cunkuan=60#elif多条件判断,else:不满足elif执行其他命令if cunkuan>1 ...
- Python中匿名函数与内置高阶函数详解
大家好,从今天起早起Python将持续更新由小甜同学从 初学者的角度 学习Python的笔记,其特点就是全文大多由 新手易理解 的 代码与注释及动态演示 .刚入门的读者千万不要错过! 很多人学习pyt ...