C語言——函數遞歸與迭代

?各位CSDN的uu們大家好呀,今天將會給大家帶來關于C語言的函數遞歸的知識,這一塊知識理解起來稍微會比較難,需要多花點時間。

話不多說,讓我們開始今天的內容吧!

目錄

1.函數遞歸

1.1 什么是遞歸?

1.2 遞歸的兩個必要條件

1.3 遞歸實例練習

2.函數的迭代

2.1 什么是迭代

2.2 遞歸與迭代實例

2.2.1 求第n個斐波那契數

2.2.2?實現n的階乘

3.總結


1.函數遞歸

1.1 什么是遞歸?

遞歸是程序調用自身的一種編程技巧,也是在程序設計語言中被廣泛應用的一種算法,一個過程或函數在其定義或說明中有直接或間接調用自身的方法,它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,這樣一來,只需少量的程序就可以描述出解題過程所需要的多次重復計算,大大減少程序的代碼量。

遞歸的思考方式:把大化小

1.2 遞歸的兩個必要條件

·在使用遞歸時一定要設定限制條件,當滿足這個限制條件時,遞歸就不再繼續;

·每次遞歸調用之后越來越接近這個限制條件。

1.3 遞歸實例練習

1.接收一個無符號整型值,按順序打印它的每一位

如:輸入1234 打印1 2 3 4

代碼實現如下:

#include<stdio.h>void print(int n)
{if (n > 9){print(n/10);}printf("%d ", n % 10);
}int main()
{int num = 0;scanf("%d", &num);print(num);return 0;
}

我們來看一下輸入1234后的運行結果:

?

?可以看到,運行結果符合我們的需求。現在讓我們一起來閱讀這段代碼,看看函數的遞歸體現在哪里:

我們在main函數中用scanf對定義的num變量進行輸入賦值,并調用print函數,將num的值傳給print,完成了main函數的編寫,我們回到main函數前面(函數先聲明(定義)后使用),開始print函數的實現;

這里print函數的實現通過畫圖給大家講解(很重要!!!):

2.函數的迭代

2.1 什么是迭代

迭代是函數利用自身已有的變量來推算需要的新變量,和遞歸直接調用自身存在一定差異,二者在某些情況下是可以相互轉換的,同種情況下,這兩種方法優先考慮迭代,因為遞歸很容易造成棧溢出,下面就通過兩個實例來感受一下迭代與遞歸的差異。

2.2 遞歸與迭代實例

2.2.1 求第n個斐波那契數

斐波那契數列是一個特殊的數列,從第三項開始,每一項都是前兩項之和,

1,1,2,3,5,8,......,(n-2),(n-1),(n-2)+(n-1)

現在我們用遞歸的方法實現一下:

#include<stdio.h>
//遞歸實現求第n個斐波那契數
int fib(int n)
{if (n <= 2)return 1;elsereturn fib(n - 2) + fib(n - 1);
}int main()
{int n = 0;scanf("%d", &n);printf("%d", fib(n));return 0;
}

但事實上,用遞歸求第n個斐波那契數會出現很多重復的計算,我們可以通過畫圖來看一下:

假設我們要求第50個斐波那契數:?

那么就要調用fib函數求第49個和第48個,求第49個和第48個又要再調用fib函數求第48、47、46個,其中第47個還調用了兩次,越往下存在的重復計算越多,這樣即浪費內存空間,又可能造成棧溢出。

為了讓大家更清晰地感受到求第n個斐波那契數需要調用fib函數的次數,我們在原先代碼基礎上改進一下:

#include<stdio.h>
int count = 0;
int fib(int n)
{
//這里計算的是第三個斐波那契數被重復計算多少次if (n == 3)count++;if (n <= 2)return 1;elsereturn fib(n - 2) + fib(n - 1);
}int main()
{int n = 0;scanf("%d", &n);/*printf("%d\n", fib(n));*/printf("%d", count);return 0;
}

我們來求一下第40個斐波那契數,運行一下看看count的值是多少:

?可以看到,count的值高達39088169,也就是說第三個斐波那契數被重復計算了39088169次。

為了避免這種不必要的大量重復計算,我們采用了非遞歸的形式改進代碼,也就是迭代,代碼實現如下:

#include<stdio.h>int fib(int n)
{int result;int pre_result;int next_older_result;result = pre_result = 1;while (n > 2){n--;next_older_result = pre_result;pre_result = result;result = pre_result + next_older_result;}return result;
}int main()
{int n = 0;scanf("%d", &n);int ret = fib(n);printf("%d", ret);return 0;
}

可以看到,在fib函數里,程序通過while循環不斷使用兩個已知變量求第三個需要的變量,這樣的方式要比直接調用函數自身(即遞歸)減少很多重復計算。

2.2.2?實現n的階乘

#include<stdio.h>//遞歸實現
int factorial(int n)
{if (n <= 1)return 1;elsereturn n * factorial(n - 1);
}//迭代實現
int  factorial(int n)
{int result = 1;while (n > 1){result *= n;n--;}return result;
}int main()
{int n = 0;scanf("%d", &n);printf("%d", factorial(n));return 0;
}

實現n的階乘和求第n個斐波那契數也是同樣的道理,uu們可以自行探究一下,用遞歸求n的階乘,會造成多少重復計算。

3.總結

我們要知道,系統分配給程序的空間是有限的,如果出現了死循環或者是死遞歸,就可能導致系統一直不停地開辟棧空間,最終耗盡棧空間,造成棧溢出的現象。

許多問題以遞歸的形式來解釋,會讓問題變得更清晰易懂,但這些問題的迭代實現往往要比遞歸實現效率更高,但同樣的,迭代實現的代碼理解起來沒有遞歸那么容易。

在能用迭代的情況下,盡量不用遞歸,除非該問題的迭代實現非常復雜,那么此時遞歸實現的簡潔性就足以彌補它運行時所產生的一系列問題。

這篇文章就到這里啦,關于遞歸與迭代的知識,還需要uu們多去找題練習,遞歸雖好,但不要經常用哦。

如果你覺得這篇文章對你有幫助的話,麻煩動動小手為我點個贊哦,你的喜歡就是我創作的動力!

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

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

相關文章

藏品館管理系統

藏品館管理系統 項目簡介 這是一個基于 PHP 開發的藏品館管理系統&#xff0c;實現了藏品管理、用戶管理等功能。 藏品館管理系統 系統架構 開發語言&#xff1a;PHP數據庫&#xff1a;MySQL前端框架&#xff1a;BootstrapJavaScript 庫&#xff1a;jQuery 目錄結構 book/…

centos停服 遷移centos7.3系統到新搭建的openEuler

背景 最近在做的事&#xff0c;簡單來講&#xff0c;就是一套系統差不多有10多臺虛擬機&#xff0c;都是centos系統&#xff0c;版本主要是7.3、7.6、7.9&#xff0c;現在centos停止維護了&#xff0c;轉為了centos stream&#xff0c;而centos stream的定位是&#xff1a;Red …

什么是 IDE?集成開發環境的功能與優勢

原文&#xff1a;什么是 IDE&#xff1f;集成開發環境的功能與優勢 | w3cschool筆記 &#xff08;注意&#xff1a;此為科普文章&#xff0c;請勿標記為付費文章&#xff01;且此文章并非我原創&#xff0c;不要標記為付費&#xff01;&#xff09; IDE 是什么&#xff1f; …

jenkins批量復制Job項目的shell腳本實現

背景 現在需要將“測試” 目錄中的所有job全部復制到 一個新目錄中 test2。可以結合jenkins提供的apilinux shell 進行實現。 測試目錄的實際文件夾名稱是 test。 腳本運行效果如下&#xff1a; [qdevsom5f-dev-hhyl shekk]$ ./copy_jenkins_job.sh 創建文件夾 test2 獲取源…

VisualSVN過期后的解決方法

作為一款不錯的源代碼管理軟件&#xff0c;svn還是有很多公司使用的。在vs中使用svn&#xff0c;大家一般用的都是VisualSVN插件。在30天試用期過后&#xff0c;它就不能被免費使用了。下面給大家講如何免費延長過期時間&#xff08;自定義天數&#xff0c;可以設定一個很大的值…

硬件工程師筆記——電子器件匯總大全

目錄 1、電阻 工作原理 歐姆定律 電阻的物理本質 一、限制電流 二、分壓作用 三、消耗電能&#xff08;將電能轉化為熱能&#xff09; 2、壓敏電阻 伏安特性 1. 過壓保護 2. 電壓調節 3. 浪涌吸收 4. 消噪與消火花 5. 高頻應用 3、電容 工作原理 &#xff08;…

[圖論]Kruskal

Kruskal 本質&#xff1a;貪心&#xff0c;對邊進行操作。存儲結構&#xff1a;邊集數組。適用對象&#xff1a;可為負權圖&#xff0c;可求最大生成樹。核心思想&#xff1a;最短的邊一定在最小生成樹(MST)上&#xff0c;對最短的邊進行貪心。算法流程&#xff1a;對全體邊集…

vulnhub five86系列靶機合集

five86 ~ VulnHubhttps://www.vulnhub.com/series/five86,272/ five86-1滲透過程 信息收集 # 主機發現 nmap 192.168.56.0/24 -Pn ? # 靶機全面掃描 nmap 192.168.56.131 -A -T4 目錄掃描 dirsearch -u http://192.168.56.131/ /robots.txt提示/ona。 /ona二層目錄掃描。 …

如何高效利用呼叫中心系統和AI語音機器人

要更好地使用呼叫中心系統和語音機器人&#xff0c;需要結合兩者的優勢&#xff0c;實現自動化、智能化、高效率的客戶服務與業務運營。以下是優化策略和具體實踐方法&#xff1a; 一、呼叫中心系統優化 1. 智能路由與IVR優化 智能ACD&#xff08;自動呼叫分配&#xff09; …

Nacos安裝及數據持久化

1.Nacos安裝及數據持久化 1.1下載nacos 下載地址&#xff1a;https://nacos.io/download/nacos-server/ 不用安裝&#xff0c;直接解壓縮即可。 1.2配置文件增加jdk環境和修改單機啟動standalone 找到bin目錄下的startup.cmd文件&#xff0c;添加以下語句(jdk路徑根據自己…

【牛客練習賽137 C】題解

比賽鏈接 C. 變化的數組(Easy Version) 題目大意 一個長度為 n n n 的非負數組 a a a&#xff0c;要求執行 k k k 次操作&#xff0c;每次操作如下&#xff1a; 有 1 2 \frac{1}{2} 21? 的概率令 a i ← a i ( a i ? m ) x , ? i ∈ [ 1 , n ] a_i \leftarrow a_…

Redis適用場景

Redis適用場景 一、加速緩存二、會話管理三、排行榜和計數器四、消息隊列五、實時分析六、分布式鎖七、地理位置數據八、限流九、數據共享十、簽到 一、加速緩存 Redis最常見的應用之一是作為緩存層&#xff0c;用于存儲頻繁訪問的數據&#xff0c;從而減輕數據庫的負載。 通過…

【LangChain4j快速入門】5分鐘用Java接入AI大模型,Spring Boot整合實戰!| 附源碼

【LangChain4j快速入門】5分鐘用Java接入AI大模型&#xff0c;Spring Boot整合實戰&#xff01; 前言&#xff1a;當Java遇上大模型 在AI浪潮席卷全球的今天&#xff0c;Java開發者如何快速擁抱大語言模型&#xff1f;LangChain4j作為專為Java打造的AI開發框架&#xff0c;以…

2025第十七屆“華中杯”大學生數學建模挑戰賽題目B 題 校園共享單車的調度與維護問題完整成品正文33頁(不含附錄)文章思路 模型 代碼 結果分享

校園共享單車運營優化與調度模型研究 摘 要 本研究聚焦校園共享單車點位布局、供需平衡、運營效率及故障車輛回收四大核心問題&#xff0c;通過構建一系列數學模型&#xff0c;系統分析與優化共享單車的運維體系。 針對問題一&#xff0c;我們建立了基于多時段觀測的庫存估算…

Unity游戲多語言工具包

由于一開始的代碼沒有考慮多語言場景&#xff0c;導致代碼中提示框和UI顯示直接用了中文&#xff0c;最近開始提取代碼的中文&#xff0c;提取起來太麻煩&#xff0c;所以拓展了之前的多語言包&#xff0c;降低了操作復雜度。最后把工具代碼提取出來到單獨項目里面&#xff0c;…

.NET MCP 文檔

MCP 概述 MCP&#xff08;Model Context Protocol&#xff09;是由 Anthropic 推出的一種開放協議&#xff0c;類似 AI 的 USB-C 擴展塢&#xff0c;用于在大模型和數據源之間建立安全的通信&#xff08;授權&#xff09;&#xff0c;讓 AI 應用能夠安全地訪問和操作本地或遠程…

【Linux】vim配置----超詳細

目錄 一、插件管理器準備 二、目錄準備 三、安裝插件 一、插件管理器準備 Vim-plug 是一個Vim插件管理器&#xff0c;利用異步并行可以快速地安裝、更新和卸載插件。它的安裝和配置都非常簡單&#xff0c;而且在操作過程中會給出很多易讀的反饋信息&#xff0c;是一個自由、…

PHP實現圖片自動添加水印效果

<?php // 設置原始圖片路徑和水印圖片路徑 $original_image original.jpg; $watermark_image watermark.png;// 創建圖片資源 $original imagecreatefromjpeg($original_image); $watermark imagecreatefrompng($watermark_image);// 獲取圖片尺寸 $original_width im…

檢查新接手LINUX服務器應用的部署情況和正在運行的服務

當接手一臺新的 Linux 服務器時&#xff0c;第一要務就是摸清系統上已經安裝部署了哪些應用和服務。 本文將以 CentOS7為例&#xff0c;詳細介紹如何系統地排查已安裝的應用和服務&#xff0c;包括它們的安裝方式和安裝位置。 1.查看系統基本信息 首先獲取系統整體信息&…

使用注解方式整合ssm時,啟動tomcat掃描不到resource下面的xxxmapper.xml問題,解決方法

解決org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xxx.mapper.方法 在Spring與Mybatis整合時&#xff0c;可能會遇到這樣的報錯 原因&#xff1a; 其原因為mapper路徑的映射錯誤&#xff0c;表示在嘗試執行某個 Mapper 接口的方法時…