递归

递归观点

递归是一种针对简朴轮回难以编程完成的题目,经由过程函数挪用本身,供应文雅处理方案的手艺。

递归都具有以下三个要点:

  • 运用 if-else 或 switch 语句来指导差别的状况。

  • 具有基本状况(base case)或住手前提(stopping condition)来住手递归。

  • 每次递归挪用都邑简化原始题目,让它不停靠近基本状况,所以能够用差别的参数挪用本身要领,直到它变成这类基本状况。这个称之为递归挪用(recursive call)。

示例,盘算阶乘

if(n == 0){ // base case
  return 0;
}else { // recursive call
  return n * factorial(n-1)
}

递归的上风--斐波那契数列

盘算阶乘很轻易运用轮回改写,某些状况下,用轮回不轻易处理的题目能够应用递归给出一个直观简朴的解法。

斐波那契数列从 0 到 1 最先,以后的每个数都是序列中的前两个数之和,经由过程递归能够简朴的完成出来。

var count = 0;

function fib(n) {
    count++;
    if(n == 0){
        return 0;
    }else if(n == 1){
        return 1;
    }else {
        return fib(n-1) + fib(n-2);
    }
}

const result = fib(10);

console.log('result',result);
console.log('count',count);
// result 55
// count 177

顺序中会涌现许多反复挪用,求第 10 个斐波那契数,就挪用了 177 次本身函数,假如尝试求出更大的斐波那契数,那末响应的挪用次数就会急剧的增添。

优化递归挪用

将盘算过的斐波那契值存起来,能够优化递归挪用。经由过程改进,求第 10 个斐波那契数,只挪用的 11 次本身函数。而且挪用本身函数的次数永远是,n + 1 次,n 代表第 n 个需求的斐波那契数。

var count = 0;
const calculated = [];

function fib(n) {
    count++;

    if(n == 0){
        return 0;
    }else if(n == 1){
        return 1;
    }else {
        if(!calculated[n-1]){
            calculated[n-1] = fib(n-1);
        }

        if(!calculated[n-2]){
            calculated[n-2] = fib(n-2);
        }
        return calculated[n-1] + calculated[n-2];
    }

}

const result = fib(10);

console.log('result',result);
console.log('count',count);
// result 55
// count 11

递归辅佐要领

有时候能够经由过程找到一个要处理的初始题目的相似题目,来找到初始题目的处理方案。这个相似的要领称之为递归辅佐要领。

举例,假如一个字符串从左读和从右读都是一样的,那末他就是一个回文串(palindrome)。能够经由过程下面的函数推断。

function palindrome(str) {
    if(str.length <= 1 ){
        return true;
    }else if(str[0] !== str[str.length - 1]){
        return false;
    }else {
        return palindrome(str.slice(1,-1));
    }
}

const result = palindrome("dddddd");

console.log(result); // ture

每次挪用 palindrome 要领时,都邑运用 str.slice 来建立一个新的字符串。
为了防止从新建立字符串,运用递归辅佐要领 isPalindrome 来举行改进。

function isPalindrome(str) {
    return palindrome(str,0,str.length-1);
}

function palindrome(str,low,high) {

    if(low >= high){
        return true;
    }else if(str[low] !== str[high]){
        return false;
    }else {
        low ++;
        high --;
        return palindrome(str,low,high);
    }
}

const result = isPalindrome("dddaaaerddd");

console.log(result); // false
    原文作者:穿越过来的键盘手
    原文地址: https://segmentfault.com/a/1190000007462862
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞