遞迴與回溯的理解

2021-10-10 13:47:07 字數 1445 閱讀 1387

遞迴是什麼?

求解問題 f(6), 由於 f(6) = n * f(5), 所以 f(6) 需要拆解成 f(5) 子問題進行求解,同理 f(5) = n * f(4) ,也需要進一步拆分,… ,直到 f(1), 這是「遞」,f(1) 解決了,由於 f(2) = 2 f(1) = 2 也解決了,… f(n)到最後也解決了,這是「歸」

所以遞迴的本質是能把問題拆分成具有相同解決思路的子問題,。。。直到最後被拆解的子問題再也不能拆分,解決了最小粒度可求解的子問題後,在「歸」的過程中自然順其自然地解決了最開始的問題

什麼時候用遞迴?

1.乙個問題可以分解成具有相同解決思路的子問題,子子問題,換句話說這些問題都能呼叫同乙個函式

2.經過層層分解的子問題最後一定是有乙個不能再分解的固定值的(即終止條件),如果沒有的話,就無窮無盡地分解子問題了,問題顯然是無解的

滿足以上兩個條件即可用遞迴解決問題

怎麼用遞迴?(四步法)

1.明確函式的功能

2.找出遞推公式和臨界條件(出口)

3.將遞推公式表達出來寫到函式裡

4.推導時間複雜度,看看會不會超時==,超時就得換

回溯是啥?

就是返回去做上一層未做完的事情,因為函式變數的存活期只在當前函式,所以變數的值為上乙個函式的值,return是一層一層的去回溯的

遞迴樣例(後續有經典題)

(1)這裡說一下斐波那契數列的結論:每月大土對數等於上兩個月的大兔對數之和,即an=an-1+an-2

得知了這個遞迴公式,我們就可以寫出遞迴函式

**實現如下

#include

int fibonacci (

int n)

intmain()

(2)我們可以用遞迴實現累加

**實現如下,若輸入3,此函式輸出3+2+1=6

int

recursion

(int n)

intmain()

回溯樣例無回溯的遞迴如下,此函式輸出 1 2 3 4 5

voida(

int x)

intmain()

(4)有回溯的遞迴,return語句每次返回一層,執行剩下的語句

**實現如下,此函式輸出1 2 3 4 5 然後開始回溯 5 4 3 2 1

voida(

int x)

intmain()

回溯與遞迴的區別

遞迴演算法是為了描述問題的某一狀態,必須用到該狀態的上一狀態,而描述上一狀態,又必須用到上一狀態的上一狀態 這種用自已來定義自己的方法,稱為遞迴定義。比如最出名的乙個問題,求斐波那契數列的第i位,如果用遞迴演算法做,就需要不斷遞迴得到前兩位的值。而回溯演算法的本質是為了得到可能存在的所有情況,當乙個...

回溯法 回溯法介紹 回溯與遞迴的區別

回溯法 有一類問題,我們不知道它明確的計算法則。而是先進行試探,試探到最終狀況,發現不滿足問題的要求,則回溯到上乙個狀態繼續試探。這種不斷試探和回溯的思想,稱為回溯法 backtrcking 此類問題包括 求最優解 一組解 全部解。例如八皇后問題 回溯的演算法思想 一直往下走,然後再一步步往回走 面...

八皇后 回溯 與 遞迴

八皇后 在8x8的棋盤上,放置8個皇后,每兩個皇后不能同時出現在乙個列上或一行上或對角線上 回溯法 用棧 陣列arr 8 表示8行,arr i 存放第i行所在的列 1 8 topid表示棧頂位置 從第1行開始賦值 從1到8嘗試 並且檢查衝突 第1行賦值成功後,開始給第2行開始賦值 從1到8嘗試 並且...