初談遞迴:程式設計師為什麼要學好數學?
簡介
首先要明白遞迴是一種演算法。程式呼叫自身的程式設計技巧成為遞迴(recursion),它通常把一個大型複雜的問題層層轉換為一個與原問題相似的規模較小的問題來求解,當遞迴條件不滿足時,遞迴前進,當遞迴條件滿足時,遞迴返回。其實遞迴不單單是我們看到的這些,他而可以是自己呼叫其他函式的遞迴。
兩個條件
遞迴不僅僅是簡單的自己呼叫自己,更重要的是一種解決問題的方法和思想。他的思想就在於將問題分解成為規模更小的,而且與原問題一致的問題,例如二分法就是運用了該種思想,不斷的縮小範圍,將問題簡化,什麼時候可以用遞迴呢?他需要滿足兩個條件:
●分解出來的子問題必須和原問題為一致的問題,並且必須比原問題要簡單
● 遞迴不能無限制的呼叫本身,必須有一個簡單的出口能使遞迴退出
斐波那契數列
對比上述的兩個條件,斐波那契數列就非常具有代表性,在這裡就響應標題,我們為什麼要學好數學,高中的時候被虐過千百遍,已知a(0)=0,a(1)=1,試證明當n>2,a(n)=a(n-1)+a(n-2),記得高中數學卷子上總是有這種型別的題,想當初在此摔過很多跟頭啊,有時候真是一摔不起!~現在才知道原來他是斐波那契數列,用程式設計很好的就驗證了這種問題。
在棧中分配一塊空間給fi,具體在堆疊中的執行流程如下,跟著下圖中的紅線走,很容易發現他是一條線。public class Fibonacci{ public static void main(String[] args){ Fibonacci fi = new Fibonacci(); int result = fi.fib(5); } public int fib(int index){ if(index == 1||index == 2){ return 1; }else{ return fib(index-1) + fib(index-2); } } }
為什麼用
程式設計師分為很多種,有的是碼農,有的是高階程式設計師,還有的是高高在上的工程師,等等。無論是哪一種程式設計師,最初的時候用的較多的就是迴圈,什麼for迴圈、while迴圈等等,有的人說遞迴就是一種巢狀迴圈,那為什麼不用for迴圈呢?對於這個問題,元芳你怎麼看?如果事情像這位仁兄說的那樣,遞迴早就不存在了,假如當我們對一個n值不確定的序列從小到大的排序,那麼我們還能用迴圈嗎?終值不確定的情況下用迴圈就不太現實了。說到這裡感覺好像是那麼回事,上邊說的都是他的優點,難道他是一個完美的人嗎?沒有缺點?No!當然不是,在上述的兩個條件中之一就是他需要分解出更多的子問題,就是需要一步一步的遞迴,在學習過程中瞭解了堆疊的概念,在我們一步步遞迴的過程中,計算機就需要不斷的給分配空間,在該文章一開頭就說了遞迴是一種演算法,我們都知道對於演算法又有兩個很重要的評估方向,一:時間複雜度,二:空間複雜度。他也是一個凡人,所以對於不同問題要不同對待。
遞迴的常規寫法
void function(mode){
if(FirstCondition){
//基本項
}
else
{
function(mode) //呼叫自身
}
}
總結
學好數學,才能在這條道上走的更遠。不要僅僅的看到他的表面,遞迴更重要的是一種思想,一種將問題分解成為規模更小的,而且與原問題一致的問題的思想,將問題簡化。