C語言之函數(shù)遞歸的實(shí)現(xiàn)
1. 概念
C語言中,函數(shù)直接或間接調(diào)用函數(shù)本身,則該函數(shù)稱為遞歸函數(shù)。
遞歸做為一種算法在程序設(shè)計(jì)語言中廣泛應(yīng)用。一個過程或函數(shù)在其定義或說明中有直接或間接調(diào)用自身的一種方法,它通常把一個大型復(fù)雜的問題層層轉(zhuǎn)化為一個與原問題相似的規(guī)模較小的問題來求解。
遞歸的主要思考方式在于:把大事化小
2. 遞歸的兩個必要條件
//例子: void func() { //... if(...) func();//調(diào)用自身 else //... }
在上面的例子中能夠看出,它必須滿足以下兩個條件:
?? 在每一次調(diào)用自己時,必須是(在某種意義上)更接近于解;?? 必須有一個終止處理或計(jì)算的限制條件,當(dāng)滿足這個限制條件的時候,遞歸便不再繼續(xù)。
??實(shí)例1:
接收一個整型值(無符號),按照順序打印他的每一位。
例如:
輸入123,輸出1 2 3
非遞歸:
#include<stdio.h> int main() { int n=123; int a = n / 100;//取百位 int b = (n / 10)%10;//取十位 int c = n % 10;//取個位 //依次輸出 printf("%d %d %d\n", a, b, c); return 0; }
遞歸:
#include<stdio.h> void Fun_c(int x) { if (x >9)//限制條件 { Fun_c(x/10); } printf("%d ", x%10); } int main() { int n; scanf("%d", &n); Fun_c(n); return 0; }
圖解:
??實(shí)例2:
編寫函數(shù)不允許創(chuàng)建臨時變量,求字符串的長度。
int Length(char* s) { if (*s == '\0')//限制條件 return 0; else return 1 + Length(s + 1); } #include<stdio.h> int main() { char* ch = "iloveC";//字符串結(jié)束標(biāo)志:'\0' int len = Length(ch); printf("%d", len); return 0; }
第一次 s=“iloveC\0”------5+1
第二次 s=“loveC\0”-----4+1
第三次 s=“oveC\0”----3+1
第四次 s=“veC\0”----2+1 ( 回退)
第五次 s=“eC\0”----1+1
第六次 s=“C\0”----1+0
第七次 s=“\0”-----0
3. 遞歸與迭代
3.1 求n的階乘
//遞歸 #include<stdio.h> int Fac(int n) { if (n == 1)//限制條件 return 1; else return n * Fac(n - 1); } int main() { int n; scanf("%d", &n); int temp = Fac(n); printf("%d\n", temp); return 0; }
//迭代 int Fac(int n) { int temp = 1; for (int i = 1; i <= n; i++) { temp = temp * i; } return temp; } #include<stdio.h> int main() { int n; scanf("%d", &n); printf("%d\n", Fac(n)); return 0; }
3.2 求第n個斐波那契數(shù)
1 1 2 3 5 8 13 21…
從第三位開始,后一項(xiàng)等于前兩項(xiàng)之和
//遞歸 #include<stdio.h> int Fib(int n) { if (n == 1 || n == 2)//限制條件 return 1; else return Fib(n - 1) + Fib(n - 2); } int main() { int n; scanf("%d", &n); printf("%d\n", Fib(n)); return 0; }
//迭代 #include<stdio.h> int Fib(int n) { int a = 1; int b = 1; int c; while (n >= 3) { c = a + b; a = b; b = c; n--; } return c; } int main() { int n; scanf("%d", &n); printf("%d\n", Fib(n)); return 0; }
注:
?? 許多問題是以遞歸的形式進(jìn)行解釋的,這只是因?yàn)樗确沁f歸的形式更為清晰。
?? 但是這些問題的迭代實(shí)現(xiàn)往往比遞歸實(shí)現(xiàn)效率更高,雖然代碼的可讀性稍微差些。
?? 當(dāng)一個問題相當(dāng)復(fù)雜,難以用迭代實(shí)現(xiàn)時,此時遞歸實(shí)現(xiàn)的簡潔性便可以補(bǔ)償它所帶來的運(yùn)行時開銷。
結(jié)束語
遞歸是函數(shù)實(shí)現(xiàn)的一個很重要的環(huán)節(jié),我們不但要理解,還要掌握,能夠熟練使用遞歸。
到此這篇關(guān)于C語言之函數(shù)遞歸的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C語言 函數(shù)遞歸內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)
如何在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)呢?現(xiàn)在小編就和大家分享一下在c/c++中實(shí)現(xiàn)函數(shù)回調(diào)的示例代碼,需要的朋友可以參考下2013-07-07剖析C++中的常量表達(dá)式與省略號的相關(guān)作用
這篇文章主要介紹了C++中的常量表達(dá)式與省略號的相關(guān)作用,以及表達(dá)式中的可變參數(shù)模板示例,需要的朋友可以參考下2016-01-01C語言數(shù)據(jù)結(jié)構(gòu)創(chuàng)建及遍歷十字鏈表
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)十字鏈表的創(chuàng)建及遍歷,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2021-10-10C++vector的insert函數(shù)用法小結(jié)
std::vector::insert是C++中用于在指定位置插入元素的函數(shù),支持插入單個元素、多個相同元素、一個范圍的元素或初始化列表中的元素,插入操作可能會使插入點(diǎn)之后的迭代器失效,并且時間復(fù)雜度為O(n),本文介紹C++vector的insert函數(shù)用法小結(jié),感興趣的朋友一起看看吧2025-03-03C++ 中pragma once 與 #ifndef _XXX_H_ #define _XXX_H_的區(qū)別
這篇文章主要介紹了C++ 中pragma once 與 #ifndef _XXX_H_ #define _XXX_H_的區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-04-04基于Matlab LBP實(shí)現(xiàn)植物葉片識別功能
局部二值模式(LBP)是由Ojala等人于2002年提出,它被用于特征提取,而且提取的特征是圖像的紋理特征。本文將利用Matlab和LBP實(shí)現(xiàn)植物葉片識別,需要的可以參考一下2022-02-02