1.递归的概念
简单的说:递归就是方法自己调用自己 ,每次调用时传入不同的变量 .递归有助于编程者解决复杂的问题 ,同时可以让代码变得简洁。(个人觉得递归很类似于循环)
2.递归能解决什么样的问题
1)各种数学问题如: 8皇后问题 ,汉诺塔,阶乘问题,迷宫问题,球和篮子的问题 。
2)各种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等.
3)将用栈解决的问题–>递归代码比较简洁
3.递归需要遵守的重要规则
1)执行一个方法时,就创建一个新的受保护的独立空间(栈空间) 2)方法的局部变量是独立的,不会相互影响,比如 n变量 3)如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据. 4)递归必须向退出递归的条件逼近,否则就是无限递归,出现 StackOverflowError,死龟了:) 5)当一个方法执行完毕,或者遇到 return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕
举例说明:
1) 递归处理数组扁平化
let arr =[100,200,300,[400,500,[49,59,80,[232,5435,77]]]]
const add=(arr)=>{
// console.log(arr);
let num =0;
arr.forEach(item => {
if(Array.isArray(item)){
num+=add(item)
}else{
num+=item
}
});
return num
}
console.log(add(arr));
2)斐波拉契数列
// 1 1 2 3 5 8 13 21 34
function fn(n){
if(n==1 || n==2) return 1;
return fn(n-1)+fn(n-2)
}
fn(5)
console.log(fn(6));
3)数组对象复杂求和
let arr1 = [
{
name: "张三",
money: 100,
children: [
{ name: "张欢欢", money: 200 },
{
name: "张乐乐",
money: 100,
children: [
{ name: "张小欢", money: 300 },
{ name: "张小乐", money: 400 },
],
},
],
},
{
name: "李四",
money: 100,
children: [
{ name: "李红红", money: 500 },
{ name: "李明明", money: 600 },
],
},
];
let num = 0;
function fn(obj) {
obj.forEach((item, index) => {
if (item.children) {
fn(item.children);
} else {
return num += item.money
}
})
}
fn(arr1)
console.log(num);
4) 递归组件
- 组件在它的模板内可以递归的调用自己,只要给组件设置 name 组件就可以了。
- 不过需要注意的是,必须给一个条件来限制数量,否则会抛出错误: `max stack size exceeded`
- 组件递归用来开发一些具体有未知层级关系的独立组件。比如:联级选择器和树形控件
function clone(o) {
var temp = {}
for (var key in o) {
if (typeof o[key] == 'object') {
temp[key] = clone(o[key])
} else {
temp[key] = o[key]
}
}
return temp
}
递归的问题
当然, 这个世界上没有啥时万能的, 递归也不例外, 首先递归并不一定适用所有情况, 很多情况用迭代远远比用递归好了解, 其次, 相对来说, 递归的效率往往要低于迭代的实现, 同时, 内存耗用也会更大, 虽然这个时候可以用尾递归来优化, 但是尾递归并不是一定能简单做到.它是依据数据结构的栈的原理,不断开辟新的内存空间以满足程序需要,而不是不断改变已有内存空间的值来满足程序需要,所以递归是一种极具消耗内存资源的算法思维,所以在现实项目中,除非代码量影响过大,否则能不用递归就不用递归.