1樓:
對於遞迴,我大致引用一位計算機競賽教練的話:
皇帝傳近臣:幫我算一下1+2+3等於多少
然後近臣傳太監:幫我算一下2+3等於多少
太監回近臣:2+3=5
然後近臣回皇帝:1+2+3=1+5=6
這裡每個人為一次函式呼叫。即是說:從頭探到尾,在尾處找到答案後,再回傳給頭。
c語言遞迴呼叫的理解
2樓:匿名使用者
所謂遞迴,簡而言之就是應用程式自身呼叫自身,以實現層次資料結構的查詢和訪問。 遞迴的使用可以使**更簡潔清晰,可讀性更好(對於初學者到不見得),但由於遞迴需要系統堆疊,所以空間消耗要比非遞迴**要大很多,而且,如果遞迴深度太大,可能系統資源會不夠用。
往往有這樣的觀點:能不用遞迴就不用遞迴,遞迴都可以用迭代來代替。
誠然,在理論上,遞迴和迭代在時間複雜度方面是等價的(在不考慮函式呼叫開銷和函式呼叫產生的堆疊開銷),但實際上遞迴確實效率比迭代低,既然這樣,遞迴沒有任何優勢,那麼是不是就,沒有使用遞迴的必要了,那遞迴的存在有何意義呢?
萬物的存在是需要時間的檢驗的,遞迴沒有被歷史所埋沒,即有存在的理由。從理論上說,所有的遞迴函式都可以轉換為迭代函式,反之亦然,然而代價通常都是比較高的。但從演算法結構來說,遞迴宣告的結構並不總能夠轉換為迭代結構,原因在於結構的引申本身屬於遞迴的概念,用迭代的方法在設計初期根本無法實現,這就像動多型的東西並不總是可以用靜多型的方法實現一樣。
這也是為什麼在結構設計時,通常採用遞迴的方式而不是採用迭代的方式的原因,一個極典型的例子類似於連結串列,使用遞迴定義及其簡單,但對於記憶體定義(陣列方式)其定義及呼叫處理說明就變得很晦澀,尤其是在遇到環鏈、圖、網格等問題時,使用迭代方式從描述到實現上都變得不現實。 因而可以從實際上說,所有的迭代可以轉換為遞迴,但遞迴不一定可以轉換為迭代。
採用遞迴演算法需要的前提條件是,當且僅當一個存在預期的收斂時,才可採用遞迴演算法,否則,就不能使用遞迴演算法。
遞迴其實是方便了程式設計師難為了機器,遞迴可以通過數學公式很方便的轉換為程式。其優點就是易理解,容易程式設計。但遞迴是用棧機制實現的,每深入一層,都要佔去一塊棧資料區域,對巢狀層數深的一些演算法,遞迴會力不從心,空間上會以記憶體崩潰而告終,而且遞迴也帶來了大量的函式呼叫,這也有許多額外的時間開銷。
所以在深度大時,它的時空性就不好了。
而迭代雖然效率高,執行時間只因迴圈次數增加而增加,沒什麼額外開銷,空間上也沒有什麼增加,但缺點就是不容易理解,編寫複雜問題時困難。
因而,「能不用遞迴就不用遞迴,遞迴都可以用迭代來代替」這樣的理解,enoch不敢苟同,還是辯證的來看待,不可一棍子打死。
3樓:匿名使用者
用遞迴演算法其實就是因為可以很簡單的理解和表達複雜的問題,所以遞迴的**對於寫程式的人來說,應該比迭代更容易.
你只需要考慮一層呼叫,然後想成一個迭代的另一種表達方式就行了!
4樓:匿名使用者
凡是遞迴能解決的問題,遞推也能解決,遞迴必然要有結束條件,你要是理解不了遞迴,就用遞推的想法來看看這個問題,用遞推來解決遞迴就要用到棧,你用棧的思想想想這個過程的前幾步應該就差不多了
5樓:核動力機器人
給你打個比方,這個遞迴和高中學的歸納法道理一樣。
不過只是反著來的
給我解釋一下c語言遞迴函式?
6樓:匿名使用者
遞迴演算法:是一種直接或者間接地呼叫自身的演算法。在計算機編寫程式中,遞迴演算法對解決一大類問題是十分有效的,它往往使演算法的描述簡潔而且易於理解。
遞迴演算法的特點
遞迴過程一般通過函式或子過程來實現。
遞迴演算法:在函式或子過程的內部,直接或者間接地呼叫自己的演算法。
遞迴演算法的實質:是把問題轉化為規模縮小了的同類問題的子問題。然後遞迴呼叫函式(或過程)來表示問題的解。
遞迴演算法解決問題的特點:
(1) 遞迴就是在過程或函式裡呼叫自身。
(2) 在使用遞迴策略時,必須有一個明確的遞迴結束條件,稱為遞迴出口。
(3) 遞迴演算法解題通常顯得很簡潔,但遞迴演算法解題的執行效率較低。所以一般不提倡用遞迴演算法設計程式。
(4) 在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存。遞迴次數過多容易造成棧溢位等。所以一般不提倡用遞迴演算法設計程式。
遞迴演算法所體現的「重複」一般有三個要求:
一是每次呼叫在規模上都有所縮小(通常是減半);
二是相鄰兩次重複之間有緊密的聯絡,前一次要為後一次做準備(通常前一次的輸出就作為後一次的輸入);
三是在問題的規模極小時必須用直接給出解答而不再進行遞迴呼叫,因而每次遞迴呼叫都是有條件的(以規模未達到直接解答的大小為條件),無條件遞迴呼叫將會成為死迴圈而不能正常結束。 例子如下:
描述:把一個整數按n(2<=n<=20)進位制表示出來,並儲存在給定字串中。比如121用二進位制表示得到結果為:「1111001」。
引數說明:s: 儲存轉換後得到的結果。
n: 待轉換的整數。
b: n進位制(2<=n<=20)
void
numbconv(char *s, int n, int b)
/* figure out first n-1 digits */
numbconv(s, n/b, b);
/* add last digit */
len = strlen(s);
s[len] = "0123456789abcdefghijklmnopqrstuvwxyz"[n%b];
s[len+1] = '\0';
}void
main(void)
exit(0);}
7樓:匿名使用者
額,抽象的說就是解決一個問題時重複使用一個動作,那麼就可以用遞迴的方式來解決,告訴電腦重複做這個動作就行.結合看一些遞迴演算法的簡單程式,應該好懂些.
8樓:申冰潔隱祺
分析一下fac()是如何執行的。假設讀入的n=3。
首先,main()函式中的y=fac(3),引起第1次函式呼叫。進入函式後實參n=3,應執行計算3*fac(2)
為了計算fac(2),引起對fac()函式的第2次呼叫(遞迴呼叫),重新進入函式fac(),實參n=2,應執行計算2*fac(1)。
為了計算fac(1),引起對函式fac()的第3次呼叫(遞迴呼叫),重新進入函式,實參n=1,應執行計算1*fac(0)。
為了計算叫fac(0),引起對函式fac()的第4次呼叫(遞迴呼叫),重新進入函式,實參n=0,此時執行f=1和return(f),完成第4次呼叫,回送結果fac(0)=1,返回到第3次呼叫層。
計算執行f=1*fac(0)和return(f),完成第3次呼叫,回送結果fac(1)=1
返回到第2次呼叫層。
計算執行f=2*fac(1)和return(f)。完成第2次呼叫,回送結果fac(2)=2,返回到第1次呼叫層。
計算執行f=3*fac(2)和return(f).完成第1次呼叫,回送結果fac(3)=6,返回到土函式。
9樓:匿名使用者
先看看下面的例子:
void fun(int i)
printf("%d\n",i);
}intmain()
後如下:好理解
了吧void fun(int i)
printf("%d\n",i/4);
}printf("%d\n",i/2);
}printf("%d\n",i);
}這樣一展開,是不是清晰多了
c語言遞迴求階乘,c語言怎麼用遞迴呼叫函式的方法求n的階乘?
舉例 用遞迴方法求n include int main int n int y printf input a integer number scanf d n y fac n printf d d n n,y return 0 int fac int n int f if n 0 printf n ...
c語言,函式,函式,c語言,函式,函式模板
那是c 自帶的模板庫,c的很少,而且 長難記且功能少,基本可以忽略。要是用c的話,函式基本要自己寫的 在c語言中如何實現函式模板 各種用 c 語言實現的模板可能在使用形式上有所不同。現以一個求和函式 sum 為例,用 c template 可寫如下 template r sum const t ar...
c語言中的abs函式,c語言中的abs函式ifabsx1x21什麼意思abs不是返回絕對值嗎
這條語句意思是 如果x1 x2的絕對值等於1,則if的條件成立,此時表示式abs x1 x2 1 的值是1,即條件成立。意思就是判斷x1 x2的差的絕對是不是等於1唄 y zeros fftsize,1 y 20 log10 abs x1 subplot 3,1,2 在matlab中,這些語句都什麼...