算法入門--理解什么是遞歸


一般來說,遞歸都是很多算法的靈魂,所以我會舉一些例子來說明什么是遞歸算法。

首先如果你有一個盒子A,A里面有許多盒子,盒子里可能又又盒子,有一把鑰匙,在這些盒子中任意一個里,你要去找到這把鑰匙,這時候你需要采用什么方法才能更快找到鑰匙?

一般來說都會打開A並且一個個翻找盒子,如果沒有鑰匙就放到一邊,如果打開還有盒子就放到一個新隊列里去待查,如果是鑰匙就大功告成,你可以想一下,如果用Python代碼去理解這個,那就是你創建了一個List列表,從列表拿取盒子比對,如果沒找到就繼續執行,如果找到就返回成功,推出循環。
偽代碼

def look_for_key(main_box):
       pile = main_box.make_a_pile_to_look_through() while pile is not empty:
       box = pile.grab_a_box()
       for item in box: 8
            if item.is_a_box(): 
               pile.append(item)
            elif item.is_a_key(): 
               print "found the key!"

但是如果用遞歸的方式去表示就不一樣了,仔細檢查盒子,遞歸會調用自己,也就是說,你定義了一個函數,名字叫check_book,如果查到盒子里有嵌套的時候,繼續調用自己,也就是check_book,再去檢查嵌套里的盒子,這樣就代碼會清爽很多。
偽代碼

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 the key!"

遞歸可以自己調用自己,上面我用了循環和遞歸兩種方式,遞歸更容易被理解,循環的程序性能更高。

遞歸的基線條件
遞歸會自己調用自己,如果不設置一個基線條件,那么程序就會一直執行下去。
例如,你現在要寫一個倒計時程序,實現3......2.....1.....exit!  這個功能

def timedown(i)
      print i 
      timedown(i-1)

你可以跑一下這段代碼,這段代碼不會被停止,因為沒有設置必要的基線條件,你需要告訴遞歸程序何時停止遞歸。
在遞歸程序中,有兩個必要條件,基線條件和遞歸條件,遞歸條件指的是函數調用自己,基線條件指的是函數不再調用自己
修改一下上面的代碼,加上基線條件:

def timedown(i)
      print i 
      if i <= 0:
         retrun
      else:
         timedown(i-1)

現在就可以達到我們要的狀態了。

遞歸棧
首先我先說一下什么是棧,也就是調用棧,舉個例子,你的角色是一個廚師。外面一大堆客人正在點菜,服務員把每一桌客人點的菜寫在了紙條上,按桌划分,現在菜單送到了你的面前,你要開始做菜了,你可以想一下,你做完一桌菜之后,就會把紙條拿開放到旁邊,相當於這桌菜做完了,這時候服務員還是會陸陸續續送菜單進來,不停的添加到你的待做菜單中。。。
這就是棧的數據結構,插入,刪除,每次讀取最上面的那個,讀完就刪除。
遞歸也用的這套結構。
用最開始那個盒子例子:
第一種循環方法,你會創建一個盒子list,所以你知道你還有多少盒子需要查。
第二種遞歸方法,你不會用到盒子list,你一直都是自己調用自己。
你也許會問,那萬一碰見盒子互相嵌套怎么破?
其實遞歸自己調用自己的時候,盒子list是存在調用棧中的,包含了所有未檢查完的盒子,因為棧替你做了跟蹤盒子list的功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM