1.明確這個函式想要幹什麼
例如,我定義了乙個函式,想要算n的階乘:
// 算 n 的階乘(假設n不為0
)def
f(n)
:return
none
第二要素:尋找遞迴結束條件
所謂遞迴,就是會在函式內部**中,呼叫這個函式本身,所以,我們必須要找出遞迴的結束條件,不然的話,會一直呼叫自己,進入無底洞。也就是說,我們需要找出當引數為啥時,遞迴結束,之後直接把結果返回,請注意,這個時候我們必須能根據這個引數的值,能夠直接知道函式的結果是什麼。
上面那個例子,當 n = 1,2時,那你應該能夠直接知道 f(n) 是啥吧?此時,f(1) = 1,f(2) = 2。完善我們函式內部的**,把第二要素加進**裡面,如下:
#當n為1或者2時,返回的是自己,也意味著函式終止
deff
(n):
if(n<=2)
:return n
第三要素:找出函式的等價關係式
第三要素就是,我們要不斷縮小引數的範圍,縮小之後,我們可以通過一些輔助的變數或者操作,使原函式的結果不變。
說白了,就是要找到原函式的乙個等價關係式,f(n) 的等價關係式為 n * f(n-1),即f(n) = n * f(n-1)。
找出了這個等價,繼續完善我們的**,我們把這個等價式寫進函式裡。如下:
def
f(n):if
(n<=2)
:return n
else
:return n*f(n-
1)
案例1:斐波那契數列
斐波那契數列的是這樣乙個數列:1、1、2、3、5、8、13、21、34….,即第一項 f(1) = 1,第二項 f(2) = 1……,第 n 專案為 f(n) = f(n-1) + f(n-2)。求第 n 項的值是多少。
1、第一遞迴函式功能
假設 f(n) 的功能是求第 n 項的值,**如下:
#定義函式為實現斐波那契數列
deff
(n):
return
none
2、找出遞迴結束的條件
顯然,當 n = 1 或者 n = 2 ,我們可以輕易著知道結果 f(1) = f(2) = 1。所以遞迴結束條件可以為 n <= 2。**如下:
#終止條件
deff
(n):
if(n<=2)
:return
1
3、找出函式的等價關係式
def
f(n)
:#先寫遞迴結束條件
if(n<=2)
:return n
#在寫遞迴的關係條件
return f(n-1)
+f(n-
2)
案例2:小青蛙跳台階
如在三階台階的情況:當青蛙第一步跳了一級台階,那麼就只剩下了兩級台階,將問題轉化成為兩級台階的跳法,當青蛙第一步跳了兩級台階,那麼就只剩下了一級台階,就將問題轉化為了一級台階的跳法。
1階台階時,有1種跳法 (1) f(1) = 1
2階台階時,有2種跳法 ([2],[1,1]) f(2) = 2
3階台階時,有3種跳法([2,1],[1,2],[1,1,1])f(3) = f(2) + f(1)
4階台階時,有5種跳法 …f(4) = f(3) + f(2)
…n階台階時,有 f(n) = f(n-2) + f(n-1) 種跳法
**實現:
def
f(n)
:#1.先確定終止條件:f(0) = 0,f(1) = 1,等價於 n<=2時,f(n) = n。
if(n<=2)
:return n
#n情況的關係
return f(n-1)
+f(n-
2)
案例3:反轉單鏈表。
反轉單鏈表。例如鍊錶為:1->2->3->4。反轉後為 4->3->2->1
鍊錶的節點定義如下:
#定義鍊錶
class
listnode
:def
__init__
(self,x)
: self.val = x
self.
next
=none
#建立[0->1->2->3->4]的鍊錶
defcreate
(arr)
: pre = listnode(0)
# pre是固定的開頭,tmp為指標
tmp = pre
for i in arr:
print
(i) tmp.
next
= listnode(i)
tmp = tmp.
next
return pre.
next
#輸出鍊錶
defprint_ll
(head)
: tmp = head
while tmp:
print
(tmp.val)
tmp=tmp.
next
defreverse_linkedlist
(head)
:#尋找結束條件
if head is
none
or head.
next
isnone
:return head
#尋找等價關係
else
: newhead=reverse_linkedlist4(head.
next
) head.
next
.next
=head
head.
next
=none
return newhead
a = create_ll(
range(5
))a = reverse_linkedlist(a)
print_ll(a)
#---> 4 3 2 1 0
思路:
把 2->3->4 遞迴成 4->3->2。不過,1 這個節點我們並沒有去碰它,所以 1 的 next 節點仍然是連線這 2。接下來只需要把節點 2 的 next 指向 1,然後把 1 的 next 指向 null。
資料 結構 遞迴
遞迴不一定非要像斐波拉契數列一樣在return中呼叫函式 遞迴的結束條件就是初始條件值 通常的方法將遞迴呼叫放在if語句中 n!通過遞迴實現 常用方法還是通過while實現 def jiecheng n if n 0 return 1 else sum n jiecheng n 1 右邊只有階乘表示...
資料結構 遞迴
所謂遞迴,就是在乙個函式,過程,或者資料結構的內部,又直接或間接出現定義本身的應用。在以下三種情況中,常常使用遞迴。比如階乘函式,我們能夠將其分解成幾個小問題來求解,比如求5!我們可以先求4!想求4!先求3!這樣一步步使問題簡化的方法,稱之為分治法。採取分治法求解,需要滿足下面三個條件 1.能夠將乙...
資料結構 遞迴
最近開始學習王爭老師的 資料結構與演算法之美 通過總結再加上自己的思考的形式記錄這門課程,文章主要作為學習歷程的記錄。遞迴是一種非常高效 簡潔的編碼技巧,一種應用非常廣泛的演算法,比如dfs深度優先搜尋 前中後序二叉樹遍歷等都是使用遞迴。基本上所有的遞迴問題都可以用遞推公式來表示。以尋找電影排數為例...