演算法之-------遞迴與遞推
阿新 • • 發佈:2018-12-16
概念
- 遞迴:從已知問題的結果出發,用迭代表達式逐步推算出問題的開始的條件,即順推法的逆過程,稱為遞迴。
- 遞推:遞推演算法是一種用若干步可重複運算來描述複雜問題的方法。遞推是序列計算中的一種常用演算法。通常是通過計算機前面的一些項來得出序列中的指定象的值。
- 遞迴與遞推區別:相對於遞迴演算法,遞推演算法免除了資料進出棧的過程,也就是說,不需要函式不斷的向邊界值靠攏,而直接從邊界出發,直到求出函式值。
演算法舉例1
- 斐波那契數列:已知f(1) = 1 , f(2) = 1 , 且滿足關係式f(n) = f(n-1) + f(n-2),則f(50)等於多少?
- 分析:根據初始條件f(1) = 1 , f(2) = 1 和關係式f(n) = f(n-1) + f(n-2),可知,f(3) = f(2) + f(1) , f(3) = f(2) + f(1) …….
- 編寫程式碼(遞迴)
public class Fibonacci {
static int fun(int n){
if(n == 1 || n == 2){
return 1 ;
}else{
return fun(n-1) + fun(n-2) ;
}
}
public static void main(String[] args) {
for(int i = 1 ; i <= 15 ; ++i)
System.out.println(fun(i));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 編寫程式碼(遞推)
static int fun2(int n){
int a[] = new int[20] ;
a[1] = 1 ;
a[2] = 1 ;
for(int i=3 ; i<=n ;i++){
a[i] = a[i-1] + a[i-2] ;
}
return a[n] ;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 執行結果:
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
演算法舉例2
- 使用遞迴計算1+2+…+100 ;
- 分析:遞迴關係為f(n) = f(n-1) + n ,遞迴出口為f(1) = 1 ;
- 編寫程式碼(遞迴):
public class Sum {
static int fun(int n){
if( n == 1){
return 1 ;
}else{
return fun(n-1) + n ;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(fun(100));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 編寫程式碼(遞推)
static int fun2(int n){
int a[] = new int [200] ;
a[1] = 1 ;
for(int i=2 ; i<=n ; i++){
a[i] = a[i-1] + i ;
}
return a[n] ;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 執行結果:
5050
- 1
演算法舉例3
- 爬樓問題:假設有n階樓梯,每次可爬1階或2階,則爬到第n層有幾種方案?
- 問題分析:假設一階時只有一種方案f(1) = 1 ; 二階時有兩種方案(即一次走一階和一次走兩階)f(2) = 2 ;三階時有3種 f(3) = 3 ;四階時有五種 f(5) = 5 ;發現遞迴規律f(n) = f(n-1) + f(n-2) ; 遞迴出口為f(1) = 1、f(2) = 2 ;
- 編寫程式碼(遞迴):
public class Ladder {
static int fun(int n){
if(n == 1){
return 1 ;
}else if(n == 2){
return 2 ;
}else{
return fun(n-1) + fun(n-2) ;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(fun(5));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 編寫程式碼(遞推):
static int fun2(int n){
int a[] = new int [200] ;
a[1] = 1 ;
a[2] = 2 ;
for(int i=3 ; i<=n ;i++){
a[i] = a[i-1] + a[i-2] ;
}
return a[n] ;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 執行結果:
8
- 1
由上述例子可知,遞迴的重點是找到遞迴關係和遞迴出口。