摘要:遞歸概念遞歸是一種針對(duì)簡(jiǎn)單循環(huán)難以編程實(shí)現(xiàn)的問(wèn)題,通過(guò)函數(shù)調(diào)用自身,提供優(yōu)雅解決方案的技術(shù)。擁有基礎(chǔ)情況或終止條件來(lái)停止遞歸。這個(gè)稱之為遞歸調(diào)用。為了避免重新創(chuàng)建字符串,使用遞歸輔助方法來(lái)進(jìn)行改良。
遞歸概念
遞歸是一種針對(duì)簡(jiǎn)單循環(huán)難以編程實(shí)現(xiàn)的問(wèn)題,通過(guò)函數(shù)調(diào)用自身,提供優(yōu)雅解決方案的技術(shù)。
遞歸都具有以下三個(gè)要點(diǎn):
使用 if-else 或 switch 語(yǔ)句來(lái)引導(dǎo)不同的情況。
擁有基礎(chǔ)情況(base case)或終止條件(stopping condition)來(lái)停止遞歸。
每次遞歸調(diào)用都會(huì)簡(jiǎn)化原始問(wèn)題,讓它不斷接近基礎(chǔ)情況,所以可以用不同的參數(shù)調(diào)用自身方法,直到它變?yōu)檫@種基礎(chǔ)情況。這個(gè)稱之為遞歸調(diào)用(recursive call)。
示例,計(jì)算階乘
if(n == 0){ // base case return 0; }else { // recursive call return n * factorial(n-1) }遞歸的優(yōu)勢(shì)--斐波那契數(shù)列
計(jì)算階乘很容易使用循環(huán)改寫(xiě),某些情況下,用循環(huán)不容易解決的問(wèn)題可以利用遞歸給出一個(gè)直觀簡(jiǎn)單的解法。
斐波那契數(shù)列從 0 到 1 開(kāi)始,之后的每個(gè)數(shù)都是序列中的前兩個(gè)數(shù)之和,通過(guò)遞歸可以簡(jiǎn)單的實(shí)現(xiàn)出來(lái)。
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
程序中會(huì)出現(xiàn)很多重復(fù)調(diào)用,求第 10 個(gè)斐波那契數(shù),就調(diào)用了 177 次自身函數(shù),如果嘗試求出更大的斐波那契數(shù),那么相應(yīng)的調(diào)用次數(shù)就會(huì)急劇的增加。
優(yōu)化遞歸調(diào)用將計(jì)算過(guò)的斐波那契值存起來(lái),可以優(yōu)化遞歸調(diào)用。通過(guò)改良,求第 10 個(gè)斐波那契數(shù),只調(diào)用的 11 次自身函數(shù)。而且調(diào)用自身函數(shù)的次數(shù)永遠(yuǎn)是,n + 1 次,n 代表第 n 個(gè)需求的斐波那契數(shù)。
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遞歸輔助方法
有時(shí)候可以通過(guò)找到一個(gè)要解決的初始問(wèn)題的類似問(wèn)題,來(lái)找到初始問(wèn)題的解決方案。這個(gè)類似的方法稱之為遞歸輔助方法。
舉例,如果一個(gè)字符串從左讀和從右讀都是一樣的,那么他就是一個(gè)回文串(palindrome)。可以通過(guò)下面的函數(shù)判斷。
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("ffffdffffd"); console.log(result); // ture
每次調(diào)用 palindrome 方法時(shí),都會(huì)使用 str.slice 來(lái)創(chuàng)建一個(gè)新的字符串。
為了避免重新創(chuàng)建字符串,使用遞歸輔助方法 isPalindrome 來(lái)進(jìn)行改良。
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("ffffdaaaerffffd"); console.log(result); // false
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/80873.html
摘要:在遞歸過(guò)程中,未完成計(jì)算的函數(shù)將會(huì)掛起壓入調(diào)用堆棧,不然遞歸結(jié)束的時(shí)候沒(méi)辦法進(jìn)行回溯。這就引出了回溯法回溯法就是在達(dá)到遞歸邊界前的某層,由于一些事實(shí)導(dǎo)致已經(jīng)不需要前往任何一個(gè)子問(wèn)題遞歸,就可以直接返回上一層。 1簡(jiǎn)介 遞歸在前端開(kāi)發(fā)中應(yīng)用還是非常廣泛的,首先DOM就是樹(shù)狀結(jié)構(gòu),而這種結(jié)構(gòu)使用遞歸去遍歷是非常合適的。然后就是對(duì)象和數(shù)組的深復(fù)制很多庫(kù)也是使用遞歸實(shí)現(xiàn)的例如jquery中的e...
摘要:終止條件遞推公式遞歸的分類通過(guò)做大量的題,根據(jù)遞歸解決不同的問(wèn)題,引申出來(lái)的幾種解決和思考的方式。我們通過(guò)層與層之間的計(jì)算關(guān)系用遞推公式表達(dá)出來(lái)做計(jì)算,經(jīng)過(guò)層層的遞歸,最終得到結(jié)果值。 showImg(https://segmentfault.com/img/remote/1460000019222330); 前言 幾個(gè)月之前就想寫(xiě)這樣一篇文章分享給大家,由于自己有心而力不足,沒(méi)有把真...
摘要:所以,遞歸在編程中同樣是很重要的一個(gè)知識(shí)點(diǎn)。舉個(gè)例子用遞歸實(shí)現(xiàn)求第個(gè)斐波那契數(shù)??偨Y(jié)起來(lái)四個(gè)字大事化小繼續(xù)舉斐波那契數(shù)的例子三遞歸是怎樣運(yùn)行的我們通過(guò)一道題目來(lái)講解。 ...
摘要:對(duì)于函數(shù)調(diào)用開(kāi)銷,可以利用尾遞歸來(lái)解決,不過(guò)目前的引擎并沒(méi)有實(shí)現(xiàn)對(duì)尾遞歸的優(yōu)化,所以最開(kāi)始我以為遞歸沒(méi)有理由比非遞歸更快。遞歸與堆棧非遞歸的算法使用一個(gè)堆棧來(lái)實(shí)現(xiàn)。 最近刷leetcode 79題 Word Search需要用到DFS算法,由于是刷leetcode,心想不能用遞歸,影響效率,于是利用stack完成。之后又利用遞歸(使用cache)實(shí)現(xiàn)了一次,結(jié)果竟然是遞歸的算法比非遞歸...
摘要:簡(jiǎn)而言之,遞歸就是自己調(diào)用自己,但是這個(gè)調(diào)用它是有一定條件的,比如子問(wèn)題須與原始問(wèn)題為同樣的事,且更為簡(jiǎn)單。當(dāng)時(shí),這層遞歸返回,也就是返回到的這層遞歸。這時(shí),至此,遞歸結(jié)束,返回結(jié)果給調(diào)用方。 showImg(https://segmentfault.com/img/bVbvZRe?w=1242&h=735); 什么是遞歸? 維基百科給出了如下定義: 程序調(diào)用自身的編程技巧稱為遞歸.遞...
摘要:遞歸一個(gè)函數(shù)可以指向并調(diào)用自身。這是的一個(gè)獨(dú)特的用法,在這個(gè)結(jié)構(gòu)下無(wú)法替代,出錯(cuò)但我們可以用下面這種方式,把遞歸函數(shù)賦值給一個(gè)變量 遞歸(Recursion) 一個(gè)函數(shù)可以指向并調(diào)用自身(call itself)。有三種方法可以達(dá)到這個(gè)目的: 函數(shù)名 arguments.callee 作用域下的一個(gè)指向該函數(shù)的變量名 上述概念引用自MDN,對(duì)遞歸概念不清楚的可以自行查看; 遞歸函數(shù)...
閱讀 3546·2021-09-09 11:39
閱讀 1291·2021-09-09 09:33
閱讀 1196·2019-08-30 15:43
閱讀 615·2019-08-29 14:08
閱讀 1793·2019-08-26 13:49
閱讀 2447·2019-08-26 10:09
閱讀 1604·2019-08-23 17:13
閱讀 2356·2019-08-23 12:57