递归是允许函数或者过程自我调用来实现对问题的减而治之(线性递归)或分而治之(二分递归)。递归总会有一个结束条件,称为递归基,如果总是满足不了递归基就会死循坏。那么废话少说,先上代码再详细的解释一下。
任意维数组的遍历:
//arr是任意维数组
Array.prototype.traverse = function() {
var temp = [];
function callback(arr) {
for(var i in arr){
if(Array.isArray(arr[i])){
callback(arr[i]);
}else if(arr.hasOwnProperty(i)){//hasOwnProperty()判断是不是自身属性
temp.push(arr[i]);
}
}
}
callback(this);
return temp;
}
console.log(arr.traverse());
每一次循环都会判断此元素是否为数组,如果是数组就继续遍历,不是的话就压入一个一维数组。
杨辉三角的二维数组实现:
//杨辉三角
function angle(n){//n是杨辉三角的维度
var arr= new Array(n);
for(var i=0;i<n;i++){
arr[i]=new Array(n);
}//创建二维数组
arr[0][0]=1;var col,row;
function callback(col,row){
if(row==0||col==row){
return 1;//每列的第一个和最后一个都是1
}else{
return (callback(col-1,row)+callback(col-1,row-1));
}//对于大于第二行的数,除了首尾为1外,都等于上行数组中同列和前一个的和
}
for(col=1;col <n ;col++){
for(row=0;row <= col;row++){
arr[col][row]=callback(col,row);//计算数组中每一个元素的值
}
}
return arr;
}
console.log(angle(20));
事实上像杨辉三角,斐波拉契数列,雹石序列,卖鸭子等问题都是数列的问题,解决起来也很简单。列出递归表达式后写程序就简单多了。
那么就根据斐波拉契数列说说递归的原理,因为它比较简单也利于理解。
function fuber(n){//n从0开始,也可以理解为下标
var fn=[];
function callback(n){
if(n==0||n==1){
return 1;
}
else{return callback(n-1)+callback(n-2);}
}
for(var i=0;i< n;i++){
fn.push(callback(i));
}
return fn;
}
console.log(fuber(20));
可以看出函数的出口是n=1或者0的时候,会返回1.如果他的n大于2的话,比如说3会转到else计算callback(2)+callback(1)而callback(1)的答案已经明显了就是1;callback(2)就会继续计算callback(1)+callback(0)嘛。结果就是1+1.第四项就是callbac(1)+callback(0)+callback(1)显然就是3啦。对于任意的n也是同样的道理,都会一层层的计算下去,直到函数计算到出口时(比如在这里n=1或者n=0)的时候再将结果带进去,然后往上计算出结果。可以抽象为入栈出栈的过程。本文主要是面向初学者,使他们理解一下递归的原理。(事实上由于复杂度为指数,几乎不会有人用递归计算斐波拉契)