資料結構 遞迴

2021-10-03 11:12:13 字數 3507 閱讀 7676

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深度優先搜尋 前中後序二叉樹遍歷等都是使用遞迴。基本上所有的遞迴問題都可以用遞推公式來表示。以尋找電影排數為例...