 Hello 算法 1.2.0 繁体中文 Kotlin 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 為例,我們可以將結果變數 res 設為函式參數,從而實現尾遞迴: // === File: recursion.kt === /* 尾遞迴 */ tailrec fun tailRecur(n: Int, res: Int): Int { // 新增 tailrec 關鍵詞,以開啟尾遞迴最佳化 // 終止條件 if (n == 0) return res // 尾遞迴呼叫 return tailRecur(n com 25 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因0 码力 | 382 页 | 18.79 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 Kotlin 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 為例,我們可以將結果變數 res 設為函式參數,從而實現尾遞迴: // === File: recursion.kt === /* 尾遞迴 */ tailrec fun tailRecur(n: Int, res: Int): Int { // 新增 tailrec 關鍵詞,以開啟尾遞迴最佳化 // 終止條件 if (n == 0) return res // 尾遞迴呼叫 return tailRecur(n com 25 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因0 码力 | 382 页 | 18.79 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 C# 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.cs === /* 尾遞迴 */ int TailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return TailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹 當處理與“分治”相關的演算法問題0 码力 | 379 页 | 18.79 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 C# 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.cs === /* 尾遞迴 */ int TailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return TailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹 當處理與“分治”相關的演算法問題0 码力 | 379 页 | 18.79 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 Dart 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.dart === /* 尾遞迴 */ int tailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 第 2 章 複雜度分析 www.hello‑algo.com 25 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹0 码力 | 378 页 | 18.77 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 Dart 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.dart === /* 尾遞迴 */ int tailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 第 2 章 複雜度分析 www.hello‑algo.com 25 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹0 码力 | 378 页 | 18.77 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 Java 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.java === /* 尾遞迴 */ int tailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹 當處理與“分治”相關的演算法問題0 码力 | 379 页 | 18.79 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 Java 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.java === /* 尾遞迴 */ int tailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹 當處理與“分治”相關的演算法問題0 码力 | 379 页 | 18.79 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 Swift 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 + ? 為例,我們可以將結果變數 res 設為函式參數,從而實現尾遞迴: // === File: recursion.swift === /* 尾遞迴 */ func tailRecur(n: Int, res: Int) -> Int { // 終止條件 if n == 0 { return res } // 尾遞迴呼叫 return tailRecur(n: n - 1, res: com 25 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因0 码力 | 379 页 | 18.79 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 Swift 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 + ? 為例,我們可以將結果變數 res 設為函式參數,從而實現尾遞迴: // === File: recursion.swift === /* 尾遞迴 */ func tailRecur(n: Int, res: Int) -> Int { // 終止條件 if n == 0 { return res } // 尾遞迴呼叫 return tailRecur(n: n - 1, res: com 25 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因0 码力 | 379 页 | 18.79 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 Python 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 res 設為函式參數,從而實現尾遞迴: # === File: recursion.py === def tail_recur(n, res): """ 尾遞迴""" # 終止條件 if n == 0: return res # 尾遞迴呼叫 return tail_recur(n - 1, res + n) 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 第 2 章 複雜度分析 www.hello‑algo.com 25 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹0 码力 | 364 页 | 18.74 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 Python 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 res 設為函式參數,從而實現尾遞迴: # === File: recursion.py === def tail_recur(n, res): """ 尾遞迴""" # 終止條件 if n == 0: return res # 尾遞迴呼叫 return tail_recur(n - 1, res + n) 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 第 2 章 複雜度分析 www.hello‑algo.com 25 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹0 码力 | 364 页 | 18.74 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 C++ 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.cpp === /* 尾遞迴 */ int tailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹 當處理與“分治”相關的演算法問題0 码力 | 379 页 | 18.79 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 C++ 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.cpp === /* 尾遞迴 */ int tailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹 當處理與“分治”相關的演算法問題0 码力 | 379 页 | 18.79 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 C语言 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.c === /* 尾遞迴 */ int tailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹 當處理與“分治”相關的演算法問題0 码力 | 392 页 | 18.83 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 C语言 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.c === /* 尾遞迴 */ int tailRecur(int n, int res) { // 終止條件 if (n == 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹 當處理與“分治”相關的演算法問題0 码力 | 392 页 | 18.83 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 JavaScript 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.js === /* 尾遞迴 */ function tailRecur(n, res) { // 終止條件 if (n === 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 第 2 章 複雜度分析 www.hello‑algo.com 25 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹0 码力 | 379 页 | 18.78 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 JavaScript 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.js === /* 尾遞迴 */ function tailRecur(n, res) { // 終止條件 if (n === 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 第 2 章 複雜度分析 www.hello‑algo.com 25 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python 預設不支持尾遞迴最佳化,因 此即使函式是尾遞迴形式,仍然可能會遇到堆疊溢位問題。 3. 遞迴樹0 码力 | 379 页 | 18.78 MB | 10 月前3
 Hello 算法 1.2.0 繁体中文 TypeScript 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.ts === /* 尾遞迴 */ function tailRecur(n: number, res: number): number { // 終止條件 if (n === 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 第 2 章 複雜度分析 www.hello‑algo.com 25 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python0 码力 | 384 页 | 18.80 MB | 10 月前3 Hello 算法 1.2.0 繁体中文 TypeScript 版限的,過深的遞迴可能導致堆疊溢位錯誤。 2. 尾遞迴 有趣的是,如果函式在返回前的最後一步才進行遞迴呼叫,則該函式可以被編譯器或直譯器最佳化,使其在 空間效率上與迭代相當。這種情況被稱為尾遞迴(tail recursion)。 ‧ 普通遞迴:當函式返回到上一層級的函式後,需要繼續執行程式碼,因此系統需要儲存上一層呼叫的上 下文。 ‧ 尾遞迴:遞迴呼叫是函式返回前的最後一個操作,這意味著函式返回到上一層級後,無須繼續執行其他 設為函式參數,從而實現尾遞迴: // === File: recursion.ts === /* 尾遞迴 */ function tailRecur(n: number, res: number): number { // 終止條件 if (n === 0) return res; // 尾遞迴呼叫 return tailRecur(n - 1, res + n); } 尾遞迴的執行過程如圖 2‑5 所示。對比普通遞迴和尾遞迴,兩者的求和操作的執行點是不同的。 ‧ 普通遞迴:求和操作是在“迴”的過程中執行的,每層返回後都要再執行一次求和操作。 ‧ 尾遞迴:求和操作是在“遞”的過程中執行的,“迴”的過程只需層層返回。 第 2 章 複雜度分析 www.hello‑algo.com 25 圖 2‑5 尾遞迴過程 Tip 請注意,許多編譯器或直譯器並不支持尾遞迴最佳化。例如,Python0 码力 | 384 页 | 18.80 MB | 10 月前3
共 25 条
- 1
- 2
- 3













