遞迴函式的使用-以C++語言為例
阿新 • • 發佈:2019-01-23
首先我來談一下遞迴的定義:遞迴過程一般通過函式或子過程來實現。遞迴方法:在函式或子過程的內部,直接或者間接地呼叫自己的演算法。可以簡單的表示成fun( r ) { fun( k ) }。當然這個遞迴是個死迴圈,永遠不停的遞迴,所以對於遞迴,必須有一個出口,用來結束遞迴函式的呼叫,並返回結果,類似於迴圈結構的終止條件。所以遞迴和迴圈也可以是等價的。
下面我們來討論一下遞迴的優缺點:
優點很明顯,程式碼簡短。
缺點:執行效率低下;容易造成棧的溢位。
下面我就以C++程式為例,通過使用二分法求一個方程如 x * x - 10 * x 在某個區間上的根。程式碼如下:
#include <iostream>
#include <cmath>
using namespace std;
inline float fx(float x)
{
return x * x - 10 * x;
}
float fun(int l, int r)
{
int m = (l + r) / 2;
float yl, yr, ym;
yl = fx(l);
yr = fx(r);
ym = fx(m);
<span style="white-space:pre"> </span>//遞迴的出口條件(精度範圍) if(fabs(ym) <= 1e-6) return m;
<span style="white-space:pre"> </span>//中間變數的函式值與右側變數的函式值同號,此時,左側變數不變,只需要將中間變數轉換成新的右側變數進行新一輪的遞迴操作即可。
if(ym * yr >0)
{
return fun(l, m);
}
<span style="white-space:pre"> </span>//此時<span style="font-family: arial, 宋體, sans-serif;">中間變數的函式值與右側變數的函式值異號,說明在這兩個端點之間必定有一個方程的根。 此時,右側變數不變,只需要將中間變數</span>
<span style="font-family: arial, 宋體, sans-serif;"> // </span><span style="font-family: arial, 宋體, sans-serif;">轉換成新的左側變數進行新一輪的遞迴操作即可。</span>
else //(ym * yr <0)
{
return fun(m, r);
}
}
int main()
{
int l, r;
cout << "請分別輸入l, r" << endl;
cin >> l >> r;
cout<<endl;
while( fx(l) * fx(r) > 0 ) //確保兩個
{
cout << "你剛剛輸入的數值無效,請重新輸入l, r" << endl;
cin >> l >> r;
}
cout << "最終求得的方程的解是:" << fun(l, r) << endl;
return 0;
}
二分演算法比較容易理解:對於區間[a,b]上連續不斷且f(a)·f(b)<0的函式y=f(x),通過不斷地把函式f(x)的零點所在的區間一分為二,使區間的兩個端點逐步逼近零點,進而得到零點近似值的方法叫二分法。當採用二分法時,必須保證所選擇的兩個端點的函式值的乘機必須是異號的,這樣才能保證在這個區間內方程必有一根。
通過遞迴方式我們可以求得這個方程的近似解。在下一節的部落格裡,我們繼續以這個方程為例,通過採用陣列的方式來實現,同時比較這兩種實現方式的效率。
以下是程式的執行結果的截圖: