【演算法】遞迴

來源:互聯網
上載者:User

標籤:部分   top   idt   strong   case   def   ==   程式   getting   

 遞迴執行個體:在盒子中尋找鑰匙

 

方法1:使用while迴圈演算法

(1) 建立一個要尋找的盒子堆。

(2) 從盒子堆取出一個盒子,在裡面找。

(3) 如果找到的是盒子,就將其加入盒子堆中,以便以後再尋找。

(4) 如果找到鑰匙,則大功告成!

(5) 回到第二步。

 

代碼
def look_for_key(main_box):    pile=main_box.make_a_pile_to_look_through()    while pile is not empty:        box=pile.grap_a_box        for item in box:            if item.is_a_box():                pile.append(item)            elif item.is_a_key():                print(‘found a key‘)

  

方法2:使用遞迴演算法

(1) 檢查盒子中的每樣東西。

(2) 如果是盒子,就回到第一步。

(3) 如果是鑰匙,就大功告成!

 

代碼
def look_for_key(box):    for item in box:        if item.is_a_box():            look_for_key(item)  #遞迴        elif item.is_a_key():            print(‘found a key‘)

  

如果使用迴圈,程式的效能可能更高;如果使用遞迴,程式可能更容易理解。如何選擇要看什麼對你來說更重要。

 

基準條件和遞迴條件

編寫遞迴函式時,必須告訴它何時停止遞迴。否則會導致無限迴圈。

 

遞迴函式兩部分

基準條件(base case)和遞迴條件(recursive case)

遞迴條件:指的是函數調用自己基準條件:指的是函數不再調用自己,從而避免形成無限迴圈。

 

樣本
def countdown(i):    print(i)    if i<=0:                       #基準條件       return     else:                          #遞迴條件        countdown(i-1) print(countdown(4))

  

棧定義

棧(stack)又名堆棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。

特點

LIFO,即後進先出(Last in, first out)

調用棧(call stack)

電腦在內部使用被稱為調用棧的棧。

樣本
def greet2(name):    print("how are you," + name + "?")def bye():    print(‘ok bye!‘) def greet(name):    print(‘hello,‘+name+‘!‘)    greet2(name)    print(‘getting ready to say bye..‘)    bye()print(greet(‘lilip‘))

  

調用過程

  1. 調用greet(‘lilip’),首先為該函數調用分配一塊記憶體
  2. 列印,hello,lilip!
  3. 調用greet2(‘lilip’),接著為這個函數調用分配一塊記憶體
  4. 電腦使用一個棧表示這些記憶體塊,其中第二個記憶體塊位於第一個記憶體塊的上面。
  5. 列印,how are you,lilip?greet2函數運行完畢,然後從函數調用返回。此時,棧頂的記憶體塊被彈出。
  6. 棧頂記憶體塊是函數greet,返回到函數greet。
  7. 列印getting ready to say bye..
  8. 調用bye()函數,棧頂添加函數bye的記憶體塊
  9. 列印,ok bye!並從這個函數返回。
  10.  返回到函數greet,此時運行完畢。從函數greet返回,

 

調用另一個函數時,當前函數暫停並處於未完成狀態。該函數的所有變數的值都還在記憶體中

這個棧用於儲存多個函數的變數,被稱為調用棧。

 

遞迴調用棧

遞迴函式也使用調用棧!

樣本

階乘遞迴函式

def fact(x):    if x==1:        return 1    else:        return x*fact(x-1) print(fact(3))

  

調用過程

代碼

調用棧

備忘

fact(3)

fact

x

3

 

第一次調用fact

x=3

if x==1:

fact

x

3

 

 

else:

fact

x

3

 

 

return x*fact(x-1)

fact

x

2

fact

x

3

 

遞迴調用

if x==1:

fact

x

2

fact

x

3

 

現在位於對fact的第二次調用中

x=2

最上面的函數調用是當前所處的調用

else:

fact

x

2

fact

x

3

 

兩個函數調用都有變數x,但這些x變數的值不同

return x*fact(x-1)

fact

x

1

fact

x

2

fact

x

3

 

在棧頂層調用中,不能訪問下面其他記憶體塊調用的x變數,反之亦然

if x==1:

fact

x

1

fact

x

2

fact

x

3

 

 

return 1

fact

x

1

fact

x

2

fact

x

3

 

從棧中彈出第一個方塊,意味著將從這個調用返回,返回1

return x*fact(x-1)

fact

x

2

fact

x

3

 

x為2

fact(x-1)返回1

最終返回2

return x*fact(x-1)

fact

x

3

 

x為3

fact(x-1)返回2

最終返回6

 

注意:

  1. 每個fact調用都有自己的x變數。在一個函數調用中不能訪問另一個的x變數。
  2. 每個函數調用都要佔用一定的記憶體,如果棧很高,就意味著電腦儲存了大量函數調用的資訊。

 

小結
  • 遞迴指的是調用自己的函數。
  • 每個遞迴函式都有兩個條件:基準條件和遞迴條件。
  • 棧有兩種操作:壓入和彈出。
  • 所有函數調用都進入調用棧。
  • 調用棧可能很長,這將佔用大量的記憶體。

 

【演算法】遞迴

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.