尾遞迴以及優化
參考文章:
淺談尾遞迴的優化方式(這篇和上面那篇都出自知乎三大程式設計大佬之一:趙劼)
一. 先看一個來自知乎的通俗例子
- 尾遞迴:
function story() {
從前有座山,山上有座廟,廟裡有個老和尚,一天老和尚對小和尚講故事:story()
// 尾遞迴,進入下一個函式不再需要上一個函式的環境了,得出結果以後直接返回
} - 非尾遞迴:
function story() {
從前有座山,山上有座廟,廟裡有個老和尚,一天老和尚對小和尚講故事:story(),小和尚聽了,找了塊豆腐撞死了
// 非尾遞迴,下一個函式結束以後此函式還有後續,所以必須儲存本身的環境以供處理返回值。
}
二. 遞迴和尾遞迴
- 我們都知道,在遞迴操作中,可能要通過棧來儲存一些當前函式的資訊。如果一個函式遞迴非常多次,就很可能引發棧溢位。
- 而尾遞迴是:如果一個函式中所有遞迴形式的呼叫都出現在函式的末尾,我們稱這個遞迴函式是尾遞迴的。當遞迴呼叫是整個函式體中最後執行的語句且它的返回值不屬於表示式的一部分時,這個遞迴呼叫就是尾遞迴。尾遞迴函式的特點是在迴歸過程中不用做任何操作(也就是說可以不用儲存函式的資訊),這個特性很重要,因為大多數現代的編譯器會利用這種特點自動生成優化的程式碼。
- 尾遞迴就是從最後開始計算,每遞迴一次就算出相應的結果。也就是說,函式呼叫出現在呼叫者函式的尾部。因為是尾部,所以根本沒有必要去儲存任何區域性變數。直接讓被呼叫的函式返回時越過呼叫者,返回到呼叫者的呼叫者去。
- 尾遞迴就是把當前的運算結果(或路徑)放在引數裡傳給下層函式,深層函式所面對的不是越來越簡單的問題,而是越來越複雜的問題,因為引數裡帶有前面若干步的運算路徑。
- 舉個例子:
//直接遞迴求連結串列的長度
int GetLengthRecursive(linklist head)
{
if(head->next == NULL)
return 0;
return (GetLengthRecursive(head->next) + 1);
}
//採用尾遞迴求連結串列的長度,藉助變數acc儲存當前連結串列的長度,不斷的累加
int GetLengthTailRecursive(linklist head,int *acc)
{
if(head->next == NULL)
return *acc;
*acc = *acc+1;
return GetLengthTailRecursive(head->next,acc);
}
相關文章
- 遞迴尾呼叫優化遞迴優化
- 【Scala】尾遞迴優化遞迴優化
- ?30 秒瞭解尾遞迴和尾遞迴優化遞迴優化
- 遞迴優化:尾呼叫和Memoization遞迴優化
- Javascript中的尾遞迴及其優化JavaScript遞迴優化
- JS尾遞迴優化斐波拉契數列JS遞迴優化
- 遞迴和尾遞迴遞迴
- 探索c#之尾遞迴編譯器優化C#遞迴編譯優化
- 面試官:用“尾遞迴”優化斐波那契函式面試遞迴優化函式
- 淺談尾遞迴遞迴
- 演算法小專欄:遞迴與尾遞迴演算法遞迴
- JavaScript和ABAP的尾遞迴JavaScript遞迴
- 尾遞迴實現深複製遞迴
- 直觀理解(尾)遞迴函式遞迴函式
- 尾遞迴(tail recursion) 的簡單使用遞迴AI
- 函數語言程式設計之尾呼叫和尾遞迴函數程式設計遞迴
- 尾呼叫優化優化
- Oracle with使用方法以及遞迴Oracle遞迴
- JavaScript, ABAP和Scala裡的尾遞迴(Tail Recursion)JavaScript遞迴AI
- 資料結構-樹以及深度、廣度優先遍歷(遞迴和非遞迴,python實現)資料結構遞迴Python
- 圖解尾呼叫優化圖解優化
- SQL with as 的用法 以及遞迴函式的寫法 遞迴層次查詢SQL遞迴函式
- 遞迴與迭代的聯絡以及優缺點(以c++為例)遞迴C++
- Oracle優化案例-定位start with connect by遞迴死迴圈資料(二十二)Oracle優化遞迴
- 尾遞迴 - 杜絕記憶體洩漏溢位爆棧遞迴記憶體
- kingbase SQL最佳化案例 ( union遞迴 改 cte遞迴 )SQL遞迴
- 快速排序【遞迴】【非遞迴】排序遞迴
- 用PostgreSQL找回618秒逝去的青春-遞迴收斂優化SQL遞迴優化
- 尾呼叫、優化和 ES6優化
- 遞迴遞迴
- 介紹迴流與重繪(Reflow & Repaint),以及如何進行優化?AI優化
- 快排的優化(非遞迴 (感覺沒變化遞迴和非遞迴)+ 三個隨機數選取準標準值(和相對的最後的位置交換) + 分割區間法)優化遞迴隨機
- 程式分析與優化 - 6 迴圈優化優化
- ACM(遞迴遞推—A)ACM遞迴
- 週而復始,往復迴圈,遞迴、尾遞迴演算法與無限極層級結構的探究和使用(Golang1.18)遞迴演算法Golang
- 舉例說明你對尾遞迴的理解,有哪些應用場景遞迴
- [譯] ES6中的尾呼叫優化優化
- ACM(遞迴遞推—I)ACM遞迴