iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0

概念

有些人認為遞迴僅是在運行過程中,直接或間接地持續呼叫自己的一個函式。

然而,我認為遞迴的基本概念更深入,它是一種將一個大問題分解成多個子問題的方法,並透過遞迴或迴圈的方式來解決這些問題。因此,遞迴的關鍵不在於如何進行遞迴,而在於如何分割問題

實作

void recursive(){
    recursive();
}

基本上,遞迴的基本概念就如上所示,但我們還需要添加終止條件,否則遞迴將無限進行下去,最終導致不可預測的結果。

Top-down

Top-down 是一種遞迴的實作方式,我們可以以計算階乘為例:

https://chart.googleapis.com/chart?cht=tx&chl=5!%20%3D%204!%20%5Ctimes%205
https://chart.googleapis.com/chart?cht=tx&chl=4!%20%3D%203!%20%5Ctimes%204
https://chart.googleapis.com/chart?cht=tx&chl=3!%20%3D%202!%20%5Ctimes%203
https://chart.googleapis.com/chart?cht=tx&chl=2!%20%3D%201!%20%5Ctimes%202
https://chart.googleapis.com/chart?cht=tx&chl=1!%20%3D%200!%20%5Ctimes%201
https://chart.googleapis.com/chart?cht=tx&chl=0!%20%3D%201

可以看出這可以整理成 https://chart.googleapis.com/chart?cht=tx&chl=%5Cbegin%7Bcases%7Df(n)%20%3D%20f(n%20-%201)%20*%20n%2Cn%20%3E%200%20%5C%5Cf(0)%20%3D%201%5Cend%7Bcases%7D 的形式,程式碼如下

int f(int n){
    if(n == 0){
        return 1;
    }
    return f(n - 1) * n;
}

而上面有說,需要設置終止條件,而這邊的終止條件就是 https://chart.googleapis.com/chart?cht=tx&chl=n%20%3D%200 的時候

Bottom-up

從 Top-down 算階乘的過程可以思考出:

  • https://chart.googleapis.com/chart?cht=tx&chl=5! 呼叫 https://chart.googleapis.com/chart?cht=tx&chl=4!
  • https://chart.googleapis.com/chart?cht=tx&chl=4! 呼叫 https://chart.googleapis.com/chart?cht=tx&chl=3!
  • https://chart.googleapis.com/chart?cht=tx&chl=3! 呼叫 https://chart.googleapis.com/chart?cht=tx&chl=2!
  • https://chart.googleapis.com/chart?cht=tx&chl=2! 呼叫 https://chart.googleapis.com/chart?cht=tx&chl=1!
  • https://chart.googleapis.com/chart?cht=tx&chl=1! 呼叫 https://chart.googleapis.com/chart?cht=tx&chl=0!
  • https://chart.googleapis.com/chart?cht=tx&chl=0! 回傳 https://chart.googleapis.com/chart?cht=tx&chl=1
  • https://chart.googleapis.com/chart?cht=tx&chl=1! 透過 https://chart.googleapis.com/chart?cht=tx&chl=0! 算出答案
  • https://chart.googleapis.com/chart?cht=tx&chl=2! 透過 https://chart.googleapis.com/chart?cht=tx&chl=1! 算出答案
  • https://chart.googleapis.com/chart?cht=tx&chl=3! 透過 https://chart.googleapis.com/chart?cht=tx&chl=2! 算出答案
  • https://chart.googleapis.com/chart?cht=tx&chl=4! 透過 https://chart.googleapis.com/chart?cht=tx&chl=3! 算出答案
  • https://chart.googleapis.com/chart?cht=tx&chl=5! 透過 https://chart.googleapis.com/chart?cht=tx&chl=4! 算出答案

然而,我們可以思考一個問題:如果我們可以從 https://chart.googleapis.com/chart?cht=tx&chl=0! 開始,然後一直計算到 https://chart.googleapis.com/chart?cht=tx&chl=5!,是否能夠節省更多步驟呢?這就是 Bottom-up 的思維方式。以下是程式碼:

int f[0] = 1;
for(int i = 1;i <= 5;i++){
    f[i] = f[i - 1] * i;
}

可以看出,Bottom-up 的思維方式更直觀。然而,選擇使用 Bottom-up 前,必須確保在計算當前問題時,所需的所有子問題答案都已經計算完成,就像上面的階乘問題一樣,因為在計算 https://chart.googleapis.com/chart?cht=tx&amp;chl=f%5B3%5D 時,https://chart.googleapis.com/chart?cht=tx&amp;chl=f%5B2%5D 必須已經被計算完成。

總結

遞迴是計算機科學中的一個重要概念,可用於解決各種問題,尤其是可以分解為較小子問題的問題。本文提供基本介紹和示例,對遞迴的基本原理以及兩種常見的實作方式(Top-down 和 Bottom-up)進行說明。

預告

明天應該會有這個章節的例題講解,不過難度不會太高,只是單純找一些題目讓大家可以更了解遞迴的概念。


上一篇
Day-11 排序例題講解
下一篇
Day-13 遞迴例題講解
系列文
從競賽程式學習資料結構與演算法30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言