算法_递归

递归:函数内部自己调用自己

导引例子 多层循环遍历数组
//test.js
var kkb=['个人介绍','工作记录',['css','html',[1,2,3]]];
//var newArr=['个人介绍','工作记录','css','html',1,2,3]; 
var newArr=[];
/* 数组扁平化:  把多层嵌套的数值中的内容都取出, 变成一维的数组*/
//console.log(kkb.length);
for(var i=0;i<kkb.length;i++){
	if(Array.isArray(kkb[i])){
		console.log('是数组');
		for(var k=0;k<kkb[i].length;k++){
			if(Array.isArray(kkb[i][k])){
				console.log('是数组');
				for(var j=0; j<kkb[i][k].length;j++){
					if(Array.isArray(kkb[i][k][j])){
						console.log('是数组');
					}else{
						console.log('不是数组');
						newArr.push(kkb[i][k][j]);
					}
				}
			}else{
				console.log('不是数组');
				newArr.push(kkb[i][k]);
			}
		}
	}else{
		console.log('不是数组');
		//往newArr数组添加数组元素
		newArr.push(kkb[i]);
	}
	
}
console.log(newArr);//(7) ["个人介绍", "工作记录", "css", "html", 1, 2, 3]
//递归
//function fn(){
//fn();
/}
简化(封装) 多层循环遍历数组元素
var kkb=['个人介绍','工作记录',['css','html',[1,2,3]]];
//var newArr=['个人介绍','工作记录','css','html',1,2,3]; 
var newArr=[];
//调用
falt(kkb);

function falt(arr){
	for(var i=0;i<arr.length;i++){
		if(Array.isArray(arr[i])){
			console.log('是数组');
			falt(arr[i]);
		}else{
			console.log('不是数组');
			//往newArr数组添加数组元素
			newArr.push(arr[i]);
		}
	}	
}
/*
 第一次循环['个人介绍','工作记录',[]]
 第二次循环['css','html',[]];
 第三次循环[1,2,3]
 falt(kkb);
 falt(['css','html',[]])
 falt([1,2,3])
*/
console.log(newArr);//(7) ["个人介绍", "工作记录", "css", "html", 1, 2, 3]
递归的执行流程
/*准备一个变量,初始值为0 ,然后在递归中 打印它0-5的值*/
var num=0;
function loop(num){
	if(num<5){
		loop(num+1);
	}
	console.log(num);
}
/* 先递后归  5  4  3  2  1*/
  • 数据存储结构 这些数据都被放在内存中
  • 特点: 先进后出
  • 案例 餐厅洗盘子,总是把刚洗好的放在最上面,最先放的在最下面。 取盘子的时候,从最上往下拿取。(后进先出)
  • 这里我们用于存储函数调用的记录,但是栈的大小并非无限的,过多的内容导致严重的性能问题,甚至栈溢出
内存
  • 存储数据的地方,但是不同的数据需要以不一样的形式进行存储。
递归的优化----尾递归
尾调用
  • 在一个函数执行的最后一步,是调用函数
function fn(){
	console.log(1);
	fn1();
}

以下情况不属于尾调用

function fn(){
	fn1();
	console.log(1);//这是最后执行的
}
function fn(){
	return fn1()+1;//最后一个执行的是:拿到fn1的返回值之后+1
}

尾调用不一定需要出现在代码最后,必须是最后一个执行的

function fn(){
	if(true){
		fn1();
	}else{
		fn2();
	}
}
尾调用优化原理

函数执行的时候,会生成一个 ‘调用记录’以栈的数据形式存放到内存中。多了以后就会产生溢出问题,我们可以利用尾调用优化。

此处有图

利用尾调用优化后的的栈存储

此处有图

  • 栈内只会存在当前函数的"调用记录",由于尾调用是最后一步,后续不在用到当前函数内的变量,位置等信息,所以可以销毁。
尾递归
  • 一个函数的执行的最后一步,是调用自己本身

阶乘案例 :1 * 2 * 3 * 4 * 5

//普通递归
function fn(n){
	if(n===1){
		return 1;
	}
	return n*fn(n-1);
}
//尾递归
function fn(n,total){
	if(n===1){
		return toal;
	}
	return fn(n-1,n*total);
}
//es6才实现了尾递归优化,但是必须在严格模式下
发布了49 篇原创文章 · 获赞 3 · 访问量 5117

猜你喜欢

转载自blog.csdn.net/weixin_43487066/article/details/90114923
今日推荐