C語言 遞迴演算法思想

2021-10-03 08:40:11 字數 2164 閱讀 9160

繼上篇博文裡介紹的c語言常見基礎演算法,本篇在於演算法的思路的整理和常見的演算法程式設計實現。

【定義】遞迴具體用法其實就是讓你把乙個問題分解成很多個類似的情況,雖然你要解決這個問題非常難,莫名其妙,要你想幾年,但是把他一直遞迴分解,就變成很好理解的單種情況,而你整個問題又是跟這個單種情況類似,把整個問題通過遞迴呼叫一層一層分解到最低階簡單的那種情況,就是你所需要理解的了。

乙個函式在它的函式體內呼叫它自身稱為遞迴呼叫。這種函式稱為遞迴函式。c語言允許函式的遞迴呼叫。在遞迴呼叫中,主調函式又是被調函式。執行遞迴函式將反覆呼叫其自身,每呼叫一次就進入新的一層。

常見的用法:1、斐波那契數列

// 計算fibonaci數列---2

intfibonaci_2

(int n)

else}0

1123

58...

.或者定義乙個公有的temp,返回該值。邊界條件可以是n=

0\n=

1

2、階乘

n!=1 (n=0,1)

n!=n*(n-1)! (n>1)

(n-1)!=(n-1)*(n-2)!

具體如下

long ff(int n)

經過n次入棧後,剩下n=1的已知值,後續全部相乘,直接得到答案,返回結果,出棧一次

3、倒序輸出字串、數字轉字元等

void

alpha_exchange_2

(void)}

void

alpha_exchange_3

(void

)alpha_exchange_3()

;printf

("%c"

,temp)

;}

void

binary_to_ascii

(unsigned

int value)

該函式出棧了n次,將每一次傳入引數出棧計算,都是結果的一部分

4、翻轉鍊錶,翻轉佇列

struct listnode*

reverselist

(struct listnode* head)

}

//遞迴實現

struct node *

reverse

(struct node *phead)

struct node *p = phead -> pnext;

struct node *pnewhead =

reverse

(p);

p -> pnext = phead;

phead ->pnext =

null

;return pnewhead;

}

優化方法介紹(尾遞迴)

從我給出的第一演算法可以看出,先進棧再出棧,遞迴的效率是很低的。速度上完全比不上迭代(迴圈)。但是尾遞迴引入了乙個新的函式引數,用這個新的函式引數來記錄中間值。普通遞迴階乘fac(x),就1個x而已,尾遞迴用2個引數fac(x,y),y存放階乘值。

int

fac(

int x,

int y)

intff

(int x)

intfac

(int x,

int y)

else

}對於這個程式我們先看函式ff,函式ff其實是對fac的乙個封裝函式,

純粹是為了輸入方便設計的,通過呼叫ff

(x)來呼叫fac

(x,1

),

這裡常數1就是當x=1的時候階乘值了,我通過走一遍當x=3時的值即為3!來說明一下。首先ff(3),x!=0,執行fac(3,1).第一次呼叫fac,x=3,y=1,x!=1,呼叫fac(x-1,yx),新的x=2,y=3*1=3,這裡可以看到,y已經累計了一次階乘值了,你會發現這個遞迴更類似於迭代了。事實上我們用了y記錄了普通遞迴時候,出棧的乘積,所以減少了出棧後的步驟。

【推薦文章】

本博文詳細介紹了遞迴的入棧和出棧的過程,需要特別強調的是遞迴的結束條件以及選用遞迴的傳入引數。

在呼叫函式之後的**是在函式返回後執行的,因此會層次的呼叫出棧的變數。

遞迴演算法思想

在知乎上面搜尋遞迴,但是普遍的回答是業務開發中不常涉及,和for迴圈差不多,消耗效能太大,不推薦使用。本著不服管的性格,我差了一些有用的資料,和大家分享下,遞迴的演算法和使用場景。為什麼要用遞迴 程式設計裡面估計最讓人摸不著頭腦的基本演算法就是遞迴了。很多時候我們看明白乙個複雜的遞迴都有點費時間,尤...

遞迴演算法思想

遞迴演算法就是在程式中不斷反覆呼叫自身來達到求解的方法。這裡的重點就是呼叫自身,這就是要求待求解的問題能夠分解為相同問題的乙個子問題。這樣通過多次遞迴呼叫,便可以完成求解。函式的遞迴呼叫分兩種情況 直接遞迴和間接遞迴。直接遞迴,即在函式中呼叫函式本身。間接遞迴,即間接呼叫乙個函式,如fun 1呼叫f...

演算法 遞迴思想

給定乙個字串 該字串沒有相同的字母 使用遞迴的方式列印出這個字串所包含字母的所有組合方式 package test1 public class num f c,0 c為待遞迴陣列,先確定第乙個字元,再確定第二個.b為所有已確定字元位的後乙個字元位 static void f char c,int b...