簡單來說,疊代法(iterative method)是用迴圈去循環重複程式碼的某些部分來得到答案,而遞迴法(recursive method)則是重複呼叫自身程式碼來得到答案。(參1)
一個可以同時使用疊代和遞迴來解釋的簡單例子:
求階乘 n! = 1 * 2 * 3 …*n
疊代法:是把已求得的數值,不斷重覆代入,再求得新數值的方法。
0! = 1
1! = 0!*1=1
2! = 1!*2 = 2
3! = 2!*3 = 6
…
n! = (n-1)! *
n
(紅色部份為已知)
JavaScript:
程式可於 jsBin online 執行. |
遞迴的種類:
直接遞迴(Direct Recursion): 函式(Function)直接呼叫本身時稱之直接遞迴。
間接遞迴(Indirect Recursion):函式呼叫另外的函式,再從另外函式呼叫原來的函式稱之間接遞迴。
階乘的數學定義式(遞迴式):
|
![]() |
其中規律的部份是 f(n) = n * f(n-1),f(n) 會呼叫自己 f(n-1),而 f(0) = 1 為確定的部份,也是遞迴的終止條件。
JavaScript:
程式可於 jsBin online 執行. |
以 4! 為例,遞迴的執行過程:
![]() |
|
一般人們較習慣用疊代的方式,因為是由已知的部分循序漸進推演,來得到答案。
遞迴方法常用於解決無法找到初始的已知部分,而是找出一套縮小問題範疇的規律,
以此規律不斷縮小問題,直到找到確定的部份。(參2)
而其中最經典的例子就是河內之塔(Tower of Hanoi):
|
若不了解此問題, 可以試玩一下河內之塔的遊戲:(參4)
以4個圓盤為例:
完整移動步驟:
![]() |
思考方式: 第一步圓盤1要移到B還是C呢?解決遞迴問題,通常初始動作不易找到, 此時需由外往內(大到小)思考,想成要移動最大圓盤由A到C,要如何處理圓盤呢? 圓盤移動方式: (1)為了完成圓盤1-4由A移到C, 必需將圓盤1-3由A移到B, 才能移動圓盤4由A移到C. (2)為了完成圓盤1-3由A移到B, 必需將圓盤1-2由A移到C, 才能移動圓盤3由A移到B. (3)為了完成圓盤1-2由A移到C, 必需將圓盤1 由A移到B, 才能移動圓盤2由A移到C. |
完整移動步驟:
![]() |
![]() |
第一步由上面說明知道要將圓盤1移到B |
既然圓盤1移到B,那圓盤2只能移到C |
![]() |
![]() |
將圓盤1由B移到C,完成圓盤1-2由A移到 C |
移圓盤3到B,再來將圓盤1-2由C移回B |
![]() |
![]() |
要將圓盤1-2由C移到B,要
先將圓盤1由C 移到A |
圓盤1移走後就可將圓盤2由C
移到B了 |
![]() |
![]() |
將圓盤1由A移到B,完成圓盤
1-3由A移到 B |
現在可以將最大圓盤4由A移到
C了,再來就是 將圓盤1-3移由B移到C |
![]() |
![]() |
要將圓盤1-3由B移到C,要
先將圓盤1-2 由B移到A, 而要將圓盤2由B移到A,就要將圓盤1由B移到C |
目的:要將圓盤3由B移到C, 圓盤1已由B移到C,再來就是把圓盤2移到A |
![]() |
![]() |
將圓盤1由C移到A,
完成圓盤1-2由B移到A |
把圓盤3由B移到C,
完成圓盤3,4移到C |
![]() |
![]() |
要將圓盤1-2由A移到C,要
先將圓盤1移到 B |
圓盤2由A移到C,
完成圓盤,2,3,4移到C |
![]() |
![]() |
最
後將圓盤1移到C |
完
成 |
遞迴解說:
由上面的例子可以發現要移動N個圓盤由A桿移到C桿,
其步驟為: |
![]() |
(1) 將1 ~
N-1個圓盤由 來源桿A 移到 暫放桿B |
![]() |
(2)
將第N個圓盤移到 目的桿C |
![]() |
(3) 再將1~ N-1個圓盤由
暫放桿B, 移到 目的桿C (完成) 而每次移動第N-1個圓盤到 目的桿 就要先將 1 ~ N-2 個圓盤全部移到 暫放桿 如此遞迴反覆直到只剩一個圓盤 |
![]() |
JavaScript:
程式可於 jsBin online執行. |
參考資料:
(1) Iteration & Recursion: http://www.advanced-ict.info/programming/recursion.html
(2) 演算法筆記: http://www.csie.ntnu.edu.tw/~u91029/IterativeRecursive.html
(3) 河內之塔wiki: http://zh.wikipedia.org /wiki/河內塔
(4) Tower of Hanoi DHTML game: http://www.dynamicdrive.com/dynamicindex12/hanoi.htm
(5) 遞迴wiki: http://zh.wikipedia.org /wiki/遞迴
如有版權問題,請告知。