递归问题

一、递归的定义

定义:程序函数直接或间接调用自身

二、递归的注意事项

-----递归不是无限循环,递归的次数必须是有限的!-----

---如果没有终止条件,会发生栈溢出(*Error)---

  • 每次执行一个方法会在JVM-栈中开辟一个内存空间,用于存放方法所需的数据,

  • 比如方法的局部变量、对象引用

注意事项

  • (1)递归必须有出口(终止条件)

  • (2)每次递归,范围逐渐缩小

    例子:计算累加和

    public class RecursionDemo1 {
       /**
        * 计算累加和
        * @param start,开始累加的值
        * @param end,结束累加的值
        * @return int 返回累加的结果
        */
       public static int addRecursion(int start,int end){
           //递归出口
           if (start == end){
               return end;
          }
    ?
           //递归调用,每次递归,范围缩小
           return start + addRecursion(start+1,end);
      }
    ?
       @Test
       public void testAddRecursion(){
           int i = RecursionDemo1.addRecursion(1, 3);
           System.out.println(i);
      }
    }
    ?
    • 递归问题

    • 方法执行完,出栈!

  • 用递归还是循环

    • 优势:简洁明了(用循环实现的用递归一定可以实现)

    • 劣势:循环速度快(但有些场景循环实现不了,必须使用递归)

    • 总结:优先使用循环,循环搞不定使用递归

三、递归的练习

1、实现斐波那契数列(求当前值和和)

(1)循环实现

//输出指定的值,以及所有值的总和  
public static int feboUsewhile(int num) {
       //分析,当前的数的和,等于前2个数的和(NUM =1\2直接给定)
       int key = 0;
       int a = 1;
       int b = 1;
       int sum = 0;
?
       for (int i = 1; i <= num; i++) {
           if (i == 1 || i == 2) {
               key = 1;
          }else{
               key = a + b;    //计算当前的数的和
               a = b;      // 设置新的需要被加数
               b = key;
          }
           sum += key;
           System.out.print(" " + key);//输入当前数的值
      }
       return sum;//返回总和
//       }
  }

(2)递归调用

//返回指定的值(递归)
private int feboUseRecursion(int num){
       //1、终止条件,num = 1或2时,返回值为1;
       if (num == 1){
           return 1;
      }else if(num == 2){
           return 1;
      } else{
           //return value(num - 1) + value(num-2);前num-1个数的和+当前的值=前num-1个数的和 +(sum())
           int i = feboUseRecursion(num -1) + feboUseRecursion(num -2);
           return i;
      }
?
  }
?
//求和,循环
public int sum(int num){
   int sum = 0;
   int value;
   for (int i = 1; i <= num; i++) {
       value = feboUseRecursion(i);
       sum += value;
       System.out.println(value);
  }
   return sum;
}
?
//另外附:
//直接打印数量无返回值,num最小从1开始,one:0,two:1,index:1
   private void feboUseRecursion2(int num,int one,int two,int index){
       if (num == 1){
           System.out.println(1);
           return;
      }
       //1、终止条件,num == index;
       if (index <= num){
           int sum = one + two ;
           System.out.println(sum);
           feboUseRecursion2(num,two,sum,index+1);
           //return value(num - 1) + value(num-2);前num-1个数的和+当前的值=前num-1个数的和 +(sum())
      }
?
  }

汉诺塔问题:

public void hannuotaRecursion(int num, char start, char mid, char end){
   if (num == 1){
   move(1,start,end);
  }else{
   hannuotaRecursion(num-1,start,end,mid);//将N-1个盘子从开始移到中间
   move(num,start,end);
   hannuotaRecursion(num-1,mid,start,end);//将N-1个盘子从中间移到最后
  }
}

 

 

 

递归问题

上一篇:神经网络权重初始化问题


下一篇:JVM 常见命令行监控工具