藍橋杯輔導視頻學習-遞歸與循環

遞歸與循環

一、理論上,任何循環都可以重寫爲遞歸形式:
     (1)有時候,爲棧限制,需要“尾遞歸
                            【注】a)遞歸會進行層層調用,可能會產生棧溢出問題,不同語言對棧的大小都有限制;
                                      b)使用尾遞歸,可以突破棧的限制,不用每次都壓棧。

     (2)java不支持尾遞歸
    
      有些語言沒有循環語句,只能使用遞歸。

      在C語言中可以使用goto語句來模擬尾遞歸。


二、循環改成遞歸
1、關鍵是發現邏輯“相似性
     遞歸:直接或間接的調用自身,那麼調用者和被調用者之間的應該有着相似性。
     相似性:如  通過循環語句去執行相應功能   <=>  遞歸在一定條件下調用自身,執行相同功能 。發現在循環過程中的相似性


2、不要忘記遞歸“出口”

     一個方法去調用它自身,不能是完全相同的環境,否則會進入類似死循環的情況,要通過參數的變化去控制遞歸的結束。


例子:



說明:

main()中用for語句、調用fun()、調用fun2()都實現了打印從0~9的功能;調用函數時使用的變量n就是爲了控制遞歸結束的變量;fun2()中使用添加變量,實現不同形式、卻有着相同作用的遞歸。


三、構造相似性

1、如果沒有明顯的相似性(或無法發現相似性),則需要主動構造其相似性(運用技巧)


2、不能相似的原因很可能是缺少參數(添加參數是主要技巧)


3、遞歸與數學上的遞推公式很類似


例1:計算數組a[] = {2,5,3,9,12,7}中元素的累加和(用遞歸)

分析:

        遞歸 <->踢皮球,緩解代碼中的邏輯,把複雜的東西推到下一層

        如:求出【. [......]】很多項的和,每個人只求其中最前面的和,剩下那些項的和留給下一層去求和,每層都這樣,並把求和結果返回給上一層。

              控制出口的變量:可以利用函數中給出起始位置和結束位置。

        練習用以下三種方式實現本題目:

        1) 、a[begin]+ (begin+1 + ... +結束)

        2)、a[0] + .... + end -1 + a[end]

        3)、折半求和  mid = (begin + end) / 2,分兩部分求和  [begin,mid) + [mid,end)


方法二與方法一類似;

方法三:因爲折半求和我不是很懂.........所以小夥伴路過會的話留言告訴我哦~


例2:判斷兩個字符串的內容是否相同:(逐字符判斷,遞歸)

分析:

        首先判斷長度是否相等,不等直接return false;

        在長度相等條件下,每一層遞歸判斷字符串中的第一個字符是否相等,是則進行下一層遞歸,否則返回false;判斷兩個字符串中的一個字符串是否爲空串,(因爲第一步已經確定了兩個字符串的長度是相同的,所以只要判斷一個是否爲空串即可),若爲空串,則兩個字符串相同。

                                                                 


四、遞歸調用

1、遞歸調用僅僅是被調函數恰爲主調函數

計算機中 方法A  調用 方法B:計算機通過棧結構,保存A的執行環境,然後去執行B,B結束時,棧中彈出A的數據,則A繼續往下執行。

調用棧:調用函數時需要保存主調函數的一些環境信息。


2、注意每次調用的層次不同

fun(int n = 9)   //調用下一層n=8時已經把n=9壓入棧中

...fun(int n = 8){

   ...fun(int n = 7){

      ...fun(int n = 6){

             .......打印6

         }打印7

       }打印8

   }打印9


3、注意每次分配形參並非同一個變量

4、注意返回的次序


總結:要通過多訓練,加深自己對遞歸的理解。

PS:本人初學,初次使用博客記筆記,有不正確或需要改進的地方還請各位多多指教~~微笑微笑



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章