递归的深度
在使用递归的时候经常会抛出StackOverflowError,顾名思义就是栈满了,而我们这里所说的栈在java中通常就是虚拟机栈(vm stack),在每个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈,动态链接,方法出口等信息,每一个方法从调用直到执行结束的过程就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
虚拟机栈的深度是固定的,所以虚拟机栈中所装的栈帧的多少取决于栈帧的大小,而栈帧的大小就取决于
局部变量表、操作数栈,动态链接,方法出口四个的大小,而我们最熟悉的应该是局部变量表,用于存储方法中定义的局部变量的,因此局部变量越多栈所能装下的栈帧也就越少。写个程序验证一下:
//局部变量表大的方法
public void large(int a) {
try {
//使用随机数确保每一个字符串都不相同,效果更明显
String b = String.valueOf(100* Math.random());
String c = String.valueOf(100* Math.random());
String d = String.valueOf(100* Math.random());
String e = String.valueOf(100* Math.random());
String f = String.valueOf(100* Math.random());
String g = String.valueOf(100* Math.random());
large(a);
} catch (StackOverflowError error) {
System.out.println("large方法 " + a + " 层");
//局部变量表小的方法
public void small(int a) {
try {
small(a);
} catch (StackOverflowError error) {
System.out.println("small方法" + a + " 层");
分别运行large方法和small方法,运行结果如下:
从结果来看,差距还是挺明显的。
递归的深度在使用递归的时候经常会抛出StackOverflowError,顾名思义就是栈满了,而我们这里所说的栈在java中通常就是虚拟机栈(vm stack),在每个方法执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈,动态链接,方法出口等信息,每一个方法从调用直到执行结束的过程就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。 虚拟机栈的深度是固定的,所以虚拟机栈中所装的栈帧的多少取决于栈...
所谓
递
归,即不断的自己调用自己的方法,每次在调用的时候,都开辟了一个独立的空间压入栈中,开始执行这个栈空间的代码(谁在栈顶谁先执行),而当代码执行完或者有返回的时候,这个空间便会销毁(出栈),而下面的空间就会开始执行后面的代码(在栈顶了,开始执行),直到也销毁,这个步骤称之为回溯
7.2.
递
归重要规则
执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
方法的局部变量是独立的,不会相互影响(即每次调用自己的方法开出新的空间,里面的局部变量独立)
如果方法中使用的是引用类型
递
归地计算出左子树和右子树的高度,然后找出这两棵子树高度中的最大值,在加1,就是树的高度,类似于前序遍历
int heightOfBinaryTree(BinaryTreeNode root){
int leftheight,rightheight;
if(root == null)
return 0;
else{
leftheight = heightOfBinaryTree(root.getLeft());
rightheight = heightOfBinar
在平时的工作或者面试中,大家一说到“
递
归”,我们会想到“自己调自己”,确实,程序调用自身的编程技巧称为
递
归(recursion)。但是在真正编写
递
归程序的时候一定要具备三个条件:
1.终结条件(满足边界条件时,停止调用自身)
2.
递
归条件(满足
递
归条件时,继续调用自身)
3.基本值(例如:下面demo中基本值就是最后一次调用自身时current的值)
public static void...
Java
中
递
归函数和for循环都可以用来实现循环操作,不过它们的实现方式是不同的。
递
归函数是指函数在其定义中调用自身的过程。
递
归函数通过参数的不断变化,达到循环的效果。
Java
中
递
归函数的实现方式与其他编程语言类似,需要注意
递
归
深度
的问题,避免栈溢出等问题。
例如,下面的代码实现了计算斐波那契数列的函数,使用
递
归方式实现:
public static int fibonacci(int n) {
if (n <= 1) {
return n;
} else {
return fibonacci(n-1) + fibonacci(n-2);
for循环是
Java
中最常用的循环结构之一,通过设置循环变量的初始值、循环条件和循环变量的步进值来实现循环操作。for循环可以简单高效地处理一些需要重复执行的任务。
例如,下面的代码使用for循环来打印数字1到10:
for (int i = 1; i <= 10; i++) {
System.out.println(i);
总的来说,
递
归函数和for循环都可以实现循环操作,具体使用哪种方式取决于具体的需求和场景。需要注意的是,在使用
递
归函数时要注意
递
归
深度
的问题,避免栈溢出等问题。