C語言---函數的遞歸與迭代

遞歸的理解與限制條件

? ? ? ? 所謂函數遞歸就是遞推加回歸的過程,就是函數自己調用自己。遞歸的思想就是把復雜的問題拆分成與原來那個大問題相似的子問題來求解,大事化小,像剝洋蔥一樣,最終把問題解決。

? ? ? ? 遞歸的限制條件:

? ? ? ? 一個遞歸程序,除了處理問題的遞歸主體之外,肯定是有遞歸的出口的(也就是遞歸的限制條件),每一次遞歸都是在棧區上給函數開辟一塊空間,沒有出口也就意味著棧沒有銷毀,最終會導致棧溢出的問題。所以每一次遞歸都要更加的接近這個限制條件才行。

遞歸舉例

????????問題1:求n的階乘。

? ? ? ? 問題分析:首先要知道什么是階乘,就比如 5!= 5 * 4 * 3 * 2 * 1 ,就是一個數從自己本身,一直累乘到1。那么這個就可以用遞歸來解決,假設我們就求5的階乘。

5! = 5 * 4 * 3 * 2 * 1

可以看成 5! = 5 * 4!

而4! = 4 * 3!

...................

從上邊的分析就可以得出一個遞歸的公式

n! = n * (n - 1)! (由這個公式,我們就可以設計出一個計算 n! 的函數)

又因為 0! = 1,所以可以把這個設置成遞歸的出口。

? ? ? ? 代碼實現:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>//Fact函數用于計算n的階乘
int Fact(int n)
{if (n == 0)return 1;elsereturn n * Fact(n - 1);
}int main()
{int number = 0;scanf("%d", &number);int res = Fact(number);printf("%d\n", res);return 0;
}

? ? ? ? 畫圖理解:

?


????????問題2:順序打印一個整數的每一位。

? ? ? ? 問題分析:假設現在有一個數字為1234,我想要順序打印它的每一位,就是依次打印 1 2 3 4。我們如果想要直接獲取到1,然后打印,這是非常困難的,但是,獲取到最后一位的4很容易,只需要 1234 % 10 就可以了,又由于我現在想要順序打印,所以4是要最后打印的,那就可以先打印前邊的123,再打印4,而打印123,又可以拆分為先打印12,再打印3.............就是一個遞歸

假設Print是我們自己設計的一個函數,專門用來順序打印數字的

那么上邊的思路就轉化如下:

--> Print(1234) --> Print(123) + 4;

--> Print(123) --> Print(12) + 3;?

--> Print(12) --> Print(1) + 2;

--> Print(1) --> 1(直接打印)

并且123,12......都是由原來的數字 num / 10 得到的

而由上邊的分析就可以知道遞歸的出口就是當打印的數字為一位數的時候,就直接打印。

如果打印的數字是兩位數,就先打印前邊的數字,再打印最后一位的數字。

? ? ? ? 代碼實現:

#include<stdio.h>
void Print(int n)
{if (n > 9)//大于9就說明是超過一位的,需要遞歸處理{Print(n / 10);printf("%d ", n % 10);//獲取n的最后一位,并且是最后打印}elseprintf("%d ", n);//如果只有一位,直接打印
}int main()
{int num = 0;scanf("%d", &num);Print(num);return 0;
}

????????畫圖理解:

????????再注意一個點,就是這里的Print函數是沒有返回值的其實,但是得先Print函數調用結束之后才會執行下邊的代碼,這也叫回歸。


????????問題3:求第n個斐波那契數

? ? ? ? 問題分析:所謂斐波那契數就是 1 1 2 3 5 8 13 21 34............其實這里的規律很容易被發現,就是從第三個數字開始,后一個數字是由前兩個數字加起來。而第一個和第二個斐波那契數,我們就可以把它看做是函數的遞歸出口。

? ? ? ? 代碼實現:

#include<stdio.h>
//Fib(n)就表示的是第n個斐波那契數
int Fib(int n)
{if (n == 1 || n == 2)return 1;elsereturn Fib(n - 1) + Fib(n - 2);
}int main()
{int num = 0;scanf("%d", &num);printf("%d\n", Fib(num));return 0;
}

????????附加:

????????還有兩個問題之前已經寫過了,是青蛙跳臺階和漢諾塔問題。鏈接如下。

????????用C語言函數遞歸實現青蛙跳臺階和漢諾塔問題-CSDN博客


遞歸與迭代

? ? ? ? 在上邊就提到過函數遞歸如果從來沒有遞歸出口的話就會導致棧溢出的問題,同樣的,就算有遞歸出口,如果遞歸的層次太深,也會導致棧溢出。

? ? ? ? 如果不用遞歸的方式,迭代也是很好的解決方式,迭代通常就是由循環來實現的。它們倆是相輔相成的,不過迭代相對來說消耗的棧空間較少。效率要高一點。

迭代舉例

????????問題1:用迭代的方式實現n的階乘。

? ? ? ? 問題分析:剛才已經說了,迭代其實就是用循環來實現的,求n的階乘可以先循環產生1~n之間的每一個數字,然后再累乘起來。

? ? ? ? 代碼實現:

#include<stdio.h>
int main()
{int res = 1;//res用來存最后的結果,初始化為1是因為便于下邊直接累乘int num = 0;scanf("%d", &num);//for循環產生1~num的數字for (int i = 1; i <= num; i++){res *= i;}printf("%d\n", res);return 0;
}

????????問題2:用迭代的方式求第n個斐波那契數

? ? ? ? 問題分析:關于斐波那契數的定義已經在上邊的遞歸里邊講到了。但是如果用遞歸求第50個斐波那契數的話,我們就會明顯的發現,遞歸的結果遲遲沒有出現,這就是上邊提到的遞歸的層次太深了,會影響效率。

用迭代的方式:

為了計算第n個斐波那契數,我們可以先定義三個變量。

int a = 1;

int b = 1;

int c = 1;//這是第三個數字,用來最后返回的結果

根據斐波那契數列的規律,c可以通過a + b來實現,然后再把a的值改為b原來的值,b的值改為c的值,而現在的c就又可以由a+b來計算了,以此迭代下去,效果如下。

下邊紅色代表斐波那契數,而黑色就代表該數是第幾個斐波那契數。

1 1 2 3 5 8 13 21.......

1 2 3 4 5 6? 7? 8.........

a b c..........................

? ?a b c.......................

最后解釋一下為什么c為1,因為如果要求的是第1或者第2個斐波那契數,就不會進入循環,所以直接初始化為1,具體大家可以看下邊的代碼。

????????代碼實現:

#include<stdio.h>
int Fib(int n)
{int a = 1;int b = 1;int c = 1;//計算第三個斐波那契數及之后的數才進入循環//另外,找規律可以發現// 計算第3個斐波那契數只要計算一次// 計算第4個斐波那契數要計算兩次.............while(n>=3){c = a + b;a = b;b = c;n--;}return c;
}int main()
{int num = 0;scanf("%d", &num);printf("%d\n", Fib(num));return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94011.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94011.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94011.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

freqtrade在docker運行一個dryrun實例

檢查配置 freqtrade trade --config user_data/config.json --strategy MlStrategy config文件,這個配置做期貨為主&#xff0c;靜態配置了交易對&#xff0c;同時端口和第一個bot要不一樣&#xff0c;不然沒有辦法進行監控&#xff0c;甚至要沖突了。10S鐘進行循環&#xff0c…

單片機學習筆記.PWM

PWM原理&#xff1a; 頻率占空比&#xff1a;精度占空比變化步距 電機驅動電路&#xff1a;利用PWM實現呼吸燈代碼 sbit LEDP2^0;//引腳定義unsigned char Time,i;//變量定義void Delay(unsigned int t)//定義延時 {while(t--); }main函數里&#xff1a;int main() {unsigned c…

【Git】解決使用SSH連接遠程倉庫時需要多次輸入密碼的問題

問題產生的原因&#xff1a;你的SSH私鑰設置了密碼短語&#xff08;passphrase&#xff09;。解決問題的方法&#xff1a;使用SSH代理&#xff08;ssh-agent&#xff09;&#xff0c;ssh-agent是一個后臺運行程序&#xff0c;它會記住你解鎖過的SSH私鑰的密碼短語&#xff0c;這…

機器學習—邏輯回歸

一介紹邏輯回歸是處理二分類問題的線性模型&#xff0c;通過sigmoid函數將線性輸出映射到[0,1]&#xff0c;輸出事件發生概率&#xff0c;廣泛用于預測與分類。如果做坐標的話&#xff0c;特征就是p1和p2&#xff0c;結果就是y紅的與綠的 二Sigma函數代碼說明Sigmoid 函數定義&…

深入解讀OpenTelemetry分布式鏈路追蹤:原理與實踐指南

深入解讀OpenTelemetry分布式鏈路追蹤&#xff1a;原理與實踐指南 分布式系統在微服務架構下&#xff0c;服務調用鏈越來越復雜&#xff0c;追蹤單次請求在各個微服務之間的執行情況成為運維與性能優化的關鍵。作為新一代開源標準&#xff0c;OpenTelemetry為分布式追蹤、指標與…

【0基礎PS】PS工具詳解--圖案圖章工具

目錄前言一、圖案圖章工具基礎認知?二、工具選項欄參數詳解?三、圖案圖章工具應用案例?總結前言 在 Adobe Photoshop 這一強大的圖像處理軟件中&#xff0c;圖案圖章工具是一個獨具特色的功能&#xff0c;它允許用戶利用預先定義好的圖案進行繪畫操作。 一、圖案圖章工具基…

劇本殺小程序系統開發:構建數字化劇本殺生態圈

在快節奏的現代生活中&#xff0c;人們越來越渴望在閑暇之余找到一種既能放松心情又能增進社交的方式。劇本殺&#xff0c;作為一種集推理、表演、社交于一體的新興娛樂形式&#xff0c;恰好滿足了這一需求。然而&#xff0c;隨著市場的不斷擴大&#xff0c;如何保持劇本殺的新…

【DL學習筆記】計算圖與自動求導

計算圖計算圖&#xff08;Computation Graph&#xff09;是一種用于描述計算過程的圖形化表示方法。在深度學習中&#xff0c;計算圖通常用于描述 網絡結構、運算過程 和數據流向。計算圖是一種有向無環圖&#xff0c;用圖形方式來表示算子與變量之間的關系&#xff0c;直觀高效…

大型地面光伏電站開發建設流程

?地面電站特特點&#xff1a;規模大&#xff0c;通常占用土地、水面等&#xff0c;地面式選址選項多&#xff0c;且不斷拓展出新的用地模式&#xff0c;地面式選址集中在山體、灘涂、沼澤、戈壁、沙漠、受污染土地等閑置或廢棄土地上。

除數博弈(動態規劃)

愛麗絲和鮑勃一起玩游戲&#xff0c;他們輪流行動。愛麗絲先手開局。最初&#xff0c;黑板上有一個數字 n 。在每個玩家的回合&#xff0c;玩家需要執行以下操作&#xff1a;選出任一 x&#xff0c;滿足 0 < x < n 且 n % x 0 。用 n - x 替換黑板上的數字 n 。如果玩家…

一起學springAI系列一:初體驗

Spring AI是干嘛的官網最權威&#xff0c;直接粘貼&#xff1a;“Spring AI”項目旨在簡化那些包含人工智能功能的應用程序的開發過程&#xff0c;同時避免不必要的復雜性。AI相關領域的功能對python的支持是最好的&#xff0c;相關供應商在出了啥功能的時候&#xff0c;都會優…

Ext JS極速項目之 Coworkee

ExtJS Coworkee 是什么? Ext JS 的 Coworkee 是一個由 Sencha 官方提供的完整員工管理應用示例,旨在展示 Ext JS 框架在企業級應用開發中的能力。 在線試用的地址是: https://examples.sencha.com/coworkee/#home 頁面效果與布局 登錄頁面: 主頁效果 左右分區結構:左…

飛算科技:原創技術重塑 Java 開發,引領行業數智化新浪潮

在科技革新的浪潮中&#xff0c;飛算科技作為一家堅持自主創新的數字科技企業&#xff0c;同時也是國家級高新技術企業&#xff0c;正深耕互聯網科技、大數據、人工智能等前沿領域&#xff0c;為眾多企業的數字化與智能化轉型提供強勁動力。?飛算科技的成長軌跡&#xff0c;是…

cesium FBO(一)渲染到紋理(RTT)

一聽到三維的RTT&#xff08;Render To Texture&#xff09;&#xff0c;似乎很神秘&#xff0c;但從底層實現一看&#xff0c;其實也就那樣&#xff0c;設計API的哪些頂級家伙已經幫你安排的明明白白了&#xff0c;咱們只需要學會怎么用就可以了。我認為得從WebGL入手&#xf…

PNP機器人機器人學術年會展示靈巧手動作捕捉方案。

2025年8月1-3日&#xff0c;第六屆中國機器人學術年會&#xff08;CCRS2025&#xff09;在長沙國際會議中心舉行&#xff0c;主題“人機共融&#xff0c;智向未來”。PNP機器人與靈巧智能聯合展出最新靈巧手模仿學習方案&#xff1a;基于少量示教數據即可快速復現復雜抓取動作&…

【45】C#入門到精通——C#調用C/C++生成動態庫.dll及C++ 生成動態庫.dll ,DllImport()方式導入 C++動態庫.dll方法總結

文章目錄1 C 生成動態庫.dll2 C#調用C/C生成動態庫.dll2.1 [DllImport()] 方式導入 C動態庫.dll2.2 調用測試3 C/C 生成通用dll,改進3.1改進后.h3.2 .cpp3.2 C# 調用4 [DllImport()] 方式導入C生成的 .dll 總結4.1 指定路徑導入4.2 .dll放在 執行目錄下&#xff08;一定要放對&…

從協議棧到ath12k_mac_op_tx的完整調用路徑

文章目錄 從協議棧到ath12k_mac_op_tx的完整調用路徑 1. 整體架構概覽 2. 詳細調用路徑分析 2.1 應用層到Socket層 2.2 協議層處理 2.3 網絡設備層到mac80211 2.4 mac80211發送入口 2.5 mac80211核心發送處理 2.6 mac80211發送核心處理 2.7 mac80211發送調度 2.8 最終驅動調用 …

WPFC#超市管理系統(4)入庫管理

入庫管理7. 商品入庫管理7.2 入庫實現顯示名稱、圖片、單位7.3 界面設計7.3 功能實現7. 商品入庫管理 數據庫中StockRecord表需要增加商品出入庫Type類型為nvarchar(50)。C#中的數據庫重新同步StockRecord表在Entity→Model中新建枚舉類型StockType namespace 超市管理系統.E…

CSS 打字特效

效果圖.wxml <view class"tips"><text>{{ tipsText }}</text><text class"tips-line">|</text> </view>.wxss .tips{padding: 50rpx 100rpx;font-size: 28rpx; } .tips-line{color: #ccc;animation: tips-line .5s al…

直播小程序 app 系統架構分析

一、引言 直播行業近年來發展迅猛&#xff0c;直播小程序和 APP 成為眾多用戶獲取直播內容以及主播進行內容輸出的重要平臺。一個完善且高效的系統架構是支撐直播業務穩定運行、提供優質用戶體驗的關鍵。本文將詳細剖析直播小程序 / APP 的系統架構&#xff0c;包括整體架構設計…