遞迴演算法向非遞迴演算法轉換

2021-09-06 04:01:24 字數 1627 閱讀 3816

遞迴演算法向非遞迴演算法轉換

遞迴演算法實際上是一種分而治之的方法,它把複雜問題分解為簡單問題來求解。對於某些複雜問題(例如hanio塔問題),遞迴演算法是一種自然且合乎邏輯的解決問題的方式,但是遞迴演算法的執行效率通常比較差。因此,在求解某些問題時,常採用遞迴演算法來分析問題,用非遞迴演算法來求解問題;另外,有些程式語言不支援遞迴,這就需要把遞迴演算法轉換為非遞迴演算法。

將遞迴演算法轉換為非遞迴演算法有兩種方法,一種是直接求值,不需要回溯;另一種是不能直接求值,需要回溯。前者使用一些變數儲存中間結果,稱為直接轉換法;後者使用棧儲存中間結果,稱為間接轉換法,下面分別討論這兩種方法。

1. 直接轉換法

直接轉換法通常用來消除尾遞迴和單向遞迴,將遞迴結構用迴圈結構來替代。

尾遞迴是指在遞迴演算法中,遞迴呼叫語句只有乙個,而且是處在演算法的最後。例如求階乘的遞迴演算法:

long fact(int n)

if (n==0) return 1;

else return n*fact(n-1);

當遞迴呼叫返回時,是返回到上一層遞迴呼叫的下一條語句,而這個返回位置正好是演算法的結束處,所以,不必利用棧來儲存返回資訊。對於尾遞迴形式的遞迴演算法,可以利用迴圈結構來替代。例如求階乘的遞迴演算法可以寫成如下迴圈結構的非遞迴演算法:

long fact(int n)

int s=0;

for (int i=1; i<=n;i++)

s=s*i; //用s儲存中間結果

return s;

單向遞迴是指遞迴演算法中雖然有多處遞迴呼叫語句,但各遞迴呼叫語句的引數之間沒有關係,並且這些遞迴呼叫語句都處在遞迴演算法的最後。顯然,尾遞迴是單向遞迴的特例。例如求斐波那契數列的遞迴演算法如下:

int f(int n)

if (n= =1 | | n= =0) return 1;

else return f(n-1)+f(n-2);

對於單向遞迴,可以設定一些變數儲存中間結構,將遞迴結構用迴圈結構來替代。例如求斐波那契數列的演算法中用s1和s2儲存中間的計算結果,非遞迴函式如下:

int f(int n)

int i, s;

int s1=1, s2=1;

for (i=3; i<=n; ++i)

s=s1+s2;

s2=s1; // 儲存f(n-2)的值

s1=s; //儲存f(n-1)的值

return s;

2. 間接轉換法

該方法使用棧儲存中間結果,一般需根據遞迴函式在執行過程中棧的變化得到。其一般過程如下:

將初始狀態s0進棧

while (棧不為空)

退棧,將棧頂元素賦給s;

if (s是要找的結果) 返回;

else

尋找到s的相關狀態s1;

將s1進棧

間接轉換法在資料結構中有較多例項,如二叉樹遍歷演算法的非遞迴實現、圖的深度優先遍歷演算法的非遞迴實現等等。

使用非遞迴方式實現遞迴問題的演算法程式,不僅可以節省儲存空間,而且可以極大地提高演算法程式的執行效率。本文將遞迴問題分成簡單遞迴問題和複雜遞迴問題;簡單遞迴問題的非遞迴實現採用遞推技術加以求解,複雜遞迴問題則根據問題求解的特點採用兩類非遞迴實現演算法,使用棧加以實現。

遞迴演算法向非遞迴演算法轉換

遞迴演算法向非遞迴演算法轉換 遞迴演算法實際上是一種分而治之的方法,它把複雜問題分解為簡單問題來求解。對於某些複雜問題 例如hanio塔問題 遞迴演算法是一種自然且合乎邏輯的解決問題的方式,但是遞迴演算法的執行效率通常比較差。因此,在求解某些問題時,常採用遞迴演算法來分析問題,用非遞迴演算法來求解問...

遞迴與非遞迴演算法

一 題目分析 將非負十進位制整n轉換成b進製 其中b 2 16 將任意正整數n用2的冪次方表示 二 演算法設計 1 轉換進製問題 exer.cpp 遞迴演算法 遞迴出口 n b b 遞迴表示式 f n,b f n b,b n b b 遞迴棧表示 2 用二的冪次方表示任意正整數n問題 exer2.cp...

遞迴 遞迴演算法的非遞迴優化

一 遞迴 在方法內部呼叫自身方法的過程稱為遞迴,下面給出乙個遞迴方法的示例。class program 使用遞迴,實現求前n項和 public static int getsum int n int result getsum n 1 在方法體中呼叫方法本身 return result n 需要注意...