摘要:在之前的文章中我們學(xué)習(xí)了幾種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),接下來(lái)我們先了解一下遞歸思想,為我們后面學(xué)習(xí)樹(shù)和圖奠定一定的基礎(chǔ)。而如果一直調(diào)用自己的話,最終會(huì)導(dǎo)致棧溢出從而導(dǎo)致程序崩潰,這是程序員不想發(fā)生的問(wèn)題之一。
在之前的文章中我們學(xué)習(xí)了幾種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),接下來(lái)我們先了解一下遞歸思想,為我們后面學(xué)習(xí)樹(shù)和圖奠定一定的基礎(chǔ)。
遞歸 理解遞歸遞歸是一種解決問(wèn)題的方法。通俗點(diǎn)來(lái)講,其核心思想就是函數(shù)自己調(diào)用自己,或者間接調(diào)用自身。而如果一直調(diào)用自己的話,最終會(huì)導(dǎo)致棧溢出從而導(dǎo)致程序崩潰,這是程序員不想發(fā)生的問(wèn)題之一。那么要使用遞歸,就必須遵循的他的一些注意點(diǎn)。首先要注意的是,每個(gè)遞歸函數(shù)都有基線條件,也就是不再發(fā)生遞歸的停止點(diǎn)。還有,既然傳遞值或者函數(shù)到棧空間,那么我們就有好習(xí)慣,將不用的或者需要的空間進(jìn)行返回。也可以這樣理解,遞歸其實(shí)就是傳遞和歸還。下面一段簡(jiǎn)單的代碼進(jìn)行展示。
function understandRecursion(doIunderstandRecursion) { const recursionAnswer = confirm("Do you understand recursion?"); // function logic if (recursionAnswer === true) { // base case or stop point return true; } understandRecursion(recursionAnswer); // recursive call } understandRecursion(false);//continue understandRecursion(false);//continue understandRecursion(true);//stop一些經(jīng)典遞歸算法 階乘
function factorialIterative(number) { if (number < 0) { return undefined; } let total = 1; for (let n = number; n > 1; n--) { total = total * n; } return total; }
function factorial(n) { // console.trace(); if (n === 1 || n === 0) { return 1; } return n * factorial(n - 1); }
值得注意的是,由于操作系統(tǒng)和瀏覽器的不同,提供的棧空間不同,也就是棧溢出發(fā)生時(shí)函數(shù)的執(zhí)行次數(shù)不同,并且在ES6中提供的是尾調(diào)用優(yōu)化,函數(shù)內(nèi)最后一個(gè)操作是調(diào)用函數(shù)時(shí),會(huì)通過(guò)跳轉(zhuǎn)指令jump而不是子程序調(diào)用,導(dǎo)致程序可以一直進(jìn)行。所以在這里,基線條件是萬(wàn)萬(wàn)不能忘了添加的。
斐波那契數(shù)列function fibonacciIterative(n){ let fibNMinus2 = 0; let fibNMinus1 = 1; let fibN = n; for (let i = 2; i <= n; i++) { // n >= 2 fibN = fibNMinus1 + fibNMinus2; // f(n-1) + f(n-2) fibNMinus2 = fibNMinus1; fibNMinus1 = fibN; } return fibN; }遞歸實(shí)現(xiàn)
function fibonacciIterative(n){ let fibNMinus2 = 0; let fibNMinus1 = 1; let fibN = n; for (let i = 2; i <= n; i++) { // n >= 2 fibN = fibNMinus1 + fibNMinus2; // f(n-1) + f(n-2) fibNMinus2 = fibNMinus1; fibNMinus1 = fibN; } return fibN; }
function fibonacciMemoization(n) { const memo = [0, 1]; const fibonacci = (n) => { if (memo[n] != null) return memo[n]; return memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo); }; return fibonacci(n); }總結(jié)
迭代版本比遞歸版本快很多,但是遞歸版本更容易理解,需要的代碼通常更少。使用遞歸有些算法不用,因?yàn)槲舱{(diào)用優(yōu)化會(huì)造成多余的內(nèi)存消耗,甚至可能會(huì)被清除。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109980.html
摘要:終止條件遞推公式遞歸的分類通過(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è)月之前就想寫這樣一篇文章分享給大家,由于自己有心而力不足,沒(méi)有把真...
摘要:一冒泡排序算法介紹比較相鄰的兩個(gè)元素如果前一個(gè)比后一個(gè)大,則交換位置。它與冒泡排序的不同之處在于,它會(huì)優(yōu)先比較距離較遠(yuǎn)的元素。希爾排序的核心在于間隔序列的設(shè)定。作為一種線性時(shí)間復(fù)雜度的排序,計(jì)數(shù)排序要求輸入的數(shù)據(jù)必須是有確定范圍的整數(shù)。 一、冒泡排序 算法介紹: 比較相鄰的兩個(gè)元素,如果前一個(gè)比后一個(gè)大,則交換位置。 第一輪把最大的元素放到了最后面。 由于每次排序最后一個(gè)都是最大的,...
摘要:八皇后問(wèn)題是十九世紀(jì)著名的數(shù)學(xué)家高斯年提出。同時(shí)可以擴(kuò)展為九皇后,十皇后問(wèn)題。解決方案回溯與遞歸。這樣,編譯器或者解釋器就可以把尾遞歸做優(yōu)化,使遞歸本身無(wú)論調(diào)用多少次,都只占用一個(gè)棧幀,不會(huì)出現(xiàn)棧溢出的情況。 八皇后問(wèn)題是十九世紀(jì)著名的數(shù)學(xué)家高斯1850年提出 。以下為python語(yǔ)言的八皇后代碼,摘自《Python基礎(chǔ)教程》,代碼相對(duì)于其他語(yǔ)言,來(lái)得短小且一次性可以打印出92種結(jié)果。...
摘要:動(dòng)態(tài)規(guī)劃法用表示最大子數(shù)組的結(jié)束下標(biāo)為的情形,則對(duì)于,有這樣就有了一個(gè)子結(jié)構(gòu),對(duì)于初始情形,遍歷就能得到這個(gè)數(shù)組,其最大者即可最大子數(shù)組的和。動(dòng)態(tài)規(guī)劃法想法巧妙,運(yùn)行效率也高,但是沒(méi)有普遍的適用性。 問(wèn)題簡(jiǎn)介 ??本文將介紹計(jì)算機(jī)算法中的經(jīng)典問(wèn)題——最大子數(shù)組問(wèn)題(maximum subarray problem)。所謂的最大子數(shù)組問(wèn)題,指的是:給定一個(gè)數(shù)組A,尋找A的和最大的非空連續(xù)...
閱讀 667·2023-04-26 02:03
閱讀 1039·2021-11-23 09:51
閱讀 1120·2021-10-14 09:42
閱讀 1742·2021-09-13 10:23
閱讀 932·2021-08-27 13:12
閱讀 845·2019-08-30 11:21
閱讀 1004·2019-08-30 11:14
閱讀 1048·2019-08-30 11:09