遞迴:簡單的講,就是定義乙個過程或函式時出現呼叫本過程或本函式就稱為遞迴。
典型的例子:
求階乘:
int
fun(
int n)
(1) 從上例就可以看出,遞迴需要終止遞迴的結束條件。
(2) 遞迴的次數必須是有限次的
(3) 可以將乙個大的問題轉化為乙個或多個與原問題相似規模較小的子問題,而這些小問題求解方法與原問題相同。
1. 函式或過程定義是遞迴的。
如,fibonacci數列:
int
fib(
int n)
2 問題求解方法是遞迴的
如,漢羅塔問題:
首先定義函式:hanio(n,x,y,z) 表示將x上的n個盤子借助y移動到z上;
將1這個問題分解:
(1)想要把n個盤子從x移動到z,也就是需要把n-1個盤子從x借助z先移動到y上, 即:hanio(n-1,x,z,y)
(2) 此時x上只有第n個盤子,直接移動到z上,即:move(n,x,z)
(3)遞迴呼叫,hanio(n-1,y,x,z)
註解:事實上,這個很好理解,相信第一步和第二步很容易理解,第三步遞迴呼叫咋回事呢?
我們定義的函式體是hanio(n,x,y,z) 執行完第(1)、(2)之後變成什麼結果呢?
即:y這根柱子現在有n-1個盤子,z上是第n盤子,x沒有盤子。
此時我們將 n-1賦值給n,將y賦值給x,將z賦值給z不就是和初始化狀態一模一樣啦,只是少了乙個盤子而已,我們呼叫函式重複第(1)、(2)步驟就ok了。即呼叫hanio(n-1,y,x,z),現在是不是懂了啊!遞迴始終是將大規模問題簡化,並且簡化後的子問題和原問題求解方法相同。源**如下:
void
hanio
(int n,
char x,
char y,
char z)
}
遞迴模型一般分為兩部分:遞迴結束出口和遞迴體。在遞迴體過程中,一般分為兩部分,對遞迴問題分解和求值兩部分。
如 階乘遞迴:以fun(5)為例
5的階乘分解和求解過程
遞迴模型的一般步驟:
(1) 首先,在大問題(第n個問題)假設合理的小問題(第n-1個問題)
(2) 確定n與n-1之間的關係,也就是確定遞迴體。
(3) 找到合理的出口,如n=0或者n=1時的解。
用棧來實現漢羅塔:
#include
#include
#include
using namespace std;
#define max 50
typedef
struct
elemtype;
typedef
struct
stackhanio;
//初始化棧
void
initstack
(stackhanio &s)
//判斷棧是否為空
bool stackempty
(stackhanio s)
//元素入棧
void
push
(stackhanio &s, elemtype e)
}//元素出棧
void
pop(stackhanio &s, elemtype &e)
}void
hanio
(int n1,
char x,
char y,
char z)
else
cout <<
"第"<
"個碟片:"
<
"-->"
<< e.z <<
"\n";}
}int
main()
[注]:如果我們用遞迴實現漢羅塔時:
將x上n個盤子借助y移動到z上
一般有以下三步:
(1)hanio(n-1,x,z,y)
(2)mov(n,x,z)
(3)hanio(n-1,y,x,z)
若使用棧時:由於棧是後進先出這種特性;
所以在**實現時與遞迴實現的(1)和(3)反過來啦,請讀者自行體會:
漢諾塔遞迴及非遞迴解法
1.經典遞迴解法 include void mov char a,char b void recursive hanoi int n,char a,char b,char c int main 2.非遞迴解法 從漢諾塔的遞迴解法可以看出,它跟二叉樹中序遍歷遞迴解法是乙個道理。既然二叉樹非遞迴解法能寫...
漢諾塔問題遞迴與非遞迴演算法
漢諾塔問題描述如下 有 a b c 3 根針,n 個圓盤 從 1.n 從上到下,按小到大順序放在 a 處,要求每次移動乙個,並保持從小到大的疊放順序,利用 c,把 n 個盤子移動到 b 處。遞迴演算法比較容易理解 fn hanoi n hanoi move n,a b c fn hanoi move...
漢諾塔的遞迴和非遞迴實現
漢諾塔的遞迴和非遞迴實現 借助堆疊以非遞迴 迴圈 方式求解漢諾塔的問題 n,a,b,c 即將n個盤子從起始柱 標記為 a 通過借助柱 標記為 b 移動到目標柱 標記為 c 並保證每個移動符合漢諾塔問題的要求。輸入為乙個正整數n,即起始柱上的盤數。每個操作 移動 佔一行,按柱1 柱2的格式輸出。3a ...