// 递归函数
// 递归函数是函数的一种特殊的用法
// 是在函数中,自己调用自己.
/*
function fun(){
fun()
}
*/
// 一般不会让我们写原生递归函数
// 基本上也是面试时会遇到
// 我们学习递归函数,主要也是为了掌握递归函数的原理
// 倒叙输出
// for循环
for(var i = 5 ; i >= 1 ; i-- ){
console.log(i);
}
// 递归方式输出
// num console.log() num-- if num >= 1 调用fun(num)
// 第一次执行 5 5 4 true num 是 4
// 第二次执行 4 4 3 true num 是 3
// 第三次执行 3 3 2 true num 是 2
// 第四次执行 2 2 1 true num 是 1
// 第五次执行 1 1 0 false 不再调用fun()本身,递归结束
function fun( num ){
console.log(num);
num--;
if(num >= 1){
fun(num);
}
}
fun(5)
// 定义一个累加求和函数,使用递归方法
// 默认是从1开始累加,累加至定义的最终数值
// 累加求和 1至前一个数的累加求和 在加上这个数值本身
// 1-100的累加求和 是 1-99的累加 再加上 100
// 1-35 的累加求和 是 1-34的累加 再加上 35
// 1-num 的累加求和 就是 1 - num-1 的累加 再加上 num本身
// 1-5累加求和 num if num == 1 return add(num-1) + num
// 第一次执行 5 false return add(4) + 5
// 第二次执行 4 false return add(3) + 4 + 5
// 第三次执行 3 false return add(2) + 3 + 4 + 5
// 第四次执行 2 false return add(1) + 2 + 3 + 4 + 5
// 第五次执行 1 true return 1 + 2 + 3 + 4 + 5
/*
执行调用 add(5)
第一次执行 add(5)
if(num == 1){
return 1;
}
return add(num-1) + num;
num 是 5 判断 if 是 false
执行 return add(num-1) + num 此时 num 是 5
实际 return add(4) + 5 add(5) 的 执行结果 是 add(4) + 5
现在是有一个调用函数 add(4) 要继续执行
第二次执行 add(4)
if(num == 1){
return 1;
}
return add(num-1) + num;
num 是 4 判断 if 是 false
执行 return add(num-1) + num 此时 num 是 4
实际 return add(3) + 4 add(4) 的 执行结果 是 add(3) + 4
现在是有一个调用函数 add(3) 要继续执行
目前 add(5) 的执行结果是 add(3) + 4 + 5
第三次执行 add(3)
if(num == 1){
return 1;
}
return add(num-1) + num;
num 是 3 判断 if 是 false
执行 return add(num-1) + num 此时 num 是 3
实际 return add(2) + 3 add(3) 的 执行结果 是 add(2) + 3
现在是有一个调用函数 add(2) 要继续执行
目前 add(5) 的执行结果是 add(2) + 3 + 4 + 5
第四次执行 add(2)
if(num == 1){
return 1;
}
return add(num-1) + num;
num 是 2 判断 if 是 false
执行 return add(num-1) + num 此时 num 是 2
实际 return add(1) + 2 add(2) 的 执行结果 是 add(1) + 2
现在是有一个调用函数 add(1) 要继续执行
目前 add(5) 的执行结果是 add(1) + 2 + 3 + 4 + 5
第五次执行 add(1)
if(num == 1){
return 1;
}
return add(num-1) + num;
num 是 1 判断 if 是 true
执行 return 1
没有任何其他的递归函数要执行,递归函数到此执行结束
目前 add(5) 的执行结果是 1 + 2 + 3 + 4 + 5
*/
function add(num){
// 当数值是1时,累加结果就是1
if(num == 1){
// 返回值也就是1
return 1;
}
// 如果不是 1 的时候
// 返回的是 当前数值前一个数值的累加 再加上 当前数值
return add(num-1) + num;
}
// 输入100,实际就是从1累加至100
console.log( add(100) );
// 阶乘的递归语法
// 5的阶乘 5! 实际就是 1*2*3*4*5 就是 4! * 5
// n的阶乘 n! 实际就是 (n-1)! 在乘上数值本身
function factorial(num){
if(num ==1){
return 1;
}
return factorial(num-1)*num;
}
console.log( factorial(5) ) ;
// 总结
// 写递归,一定是先写终止情况,也就是最后的情况
// 之后我们按照递归程序的需要,来调用函数自己本身
// 每次调用递归,参数数值一定都会不同,而且是想着最终情况改变
// 实际项目中要慎用递归
// 执行递归时,要调用生成大量的函数,这些函数都会存储在内存中,会降低内存的效率
// 一般是函数程序简单,执行次数比较少的程序,我们才使用递归方式
// 实际项目中,在前端,递归比较少见
菲波那切数列
// 使用递归生成菲波那切数列
// 1 1 2 3 5 8 13 21 34 55 .....
// 第一位,第二位都是 1
// 当前位数值 是前两位数值的和
// 求第n位上, 菲波那切数列的数值
function fun(n){
// 第一位第二位数值都是 1
if( n == 1 || n == 2 ){
return 1;
}
// 之后的数值是前两位数值的和
return fun(n-1) + fun(n-2);
}
console.log( fun(50) );
// 特别提醒,递归程序,不易执行次数过多
// 否则一定会影响程序的正常执行