
- C程式設計教程
- C - 首頁
- C語言基礎
- C - 概述
- C - 特性
- C - 歷史
- C - 環境搭建
- C - 程式結構
- C - Hello World
- C - 編譯過程
- C - 註釋
- C - 詞法單元
- C - 關鍵字
- C - 識別符號
- C - 使用者輸入
- C - 基本語法
- C - 資料型別
- C - 變數
- C - 整數提升
- C - 型別轉換
- C - 型別強制轉換
- C - 布林型別
- C語言中的常量和字面量
- C - 常量
- C - 字面量
- C - 轉義序列
- C - 格式說明符
- C語言中的運算子
- C - 運算子
- C - 算術運算子
- C - 關係運算符
- C - 邏輯運算子
- C - 位運算子
- C - 賦值運算子
- C - 一元運算子
- C - 自增和自減運算子
- C - 三元運算子
- C - sizeof 運算子
- C - 運算子優先順序
- C - 其他運算子
- C語言中的決策
- C - 決策
- C - if 語句
- C - if...else 語句
- C - 巢狀 if 語句
- C - switch 語句
- C - 巢狀 switch 語句
- C語言中的迴圈
- C - 迴圈
- C - while 迴圈
- C - for 迴圈
- C - do...while 迴圈
- C - 巢狀迴圈
- C - 無限迴圈
- C - break 語句
- C - continue 語句
- C - goto 語句
- C語言中的函式
- C - 函式
- C - 主函式
- C - 按值呼叫函式
- C - 按引用呼叫函式
- C - 巢狀函式
- C - 可變引數函式
- C - 使用者自定義函式
- C - 回撥函式
- C - 返回語句
- C - 遞迴
- C語言中的作用域規則
- C - 作用域規則
- C - 靜態變數
- C - 全域性變數
- C語言中的陣列
- C - 陣列
- C - 陣列的特性
- C - 多維陣列
- C - 將陣列傳遞給函式
- C - 從函式返回陣列
- C - 可變長陣列
- C語言中的指標
- C - 指標
- C - 指標和陣列
- C - 指標的應用
- C - 指標運算
- C - 指標陣列
- C - 指向指標的指標
- C - 將指標傳遞給函式
- C - 從函式返回指標
- C - 函式指標
- C - 指向陣列的指標
- C - 指向結構體的指標
- C - 指標鏈
- C - 指標與陣列
- C - 字元指標和函式
- C - 空指標
- C - void 指標
- C - 野指標
- C - 解引用指標
- C - 近、遠和巨型指標
- C - 指標陣列的初始化
- C - 指標與多維陣列
- C語言中的字串
- C - 字串
- C - 字串陣列
- C - 特殊字元
- C語言中的結構體和聯合體
- C - 結構體
- C - 結構體和函式
- C - 結構體陣列
- C - 自引用結構體
- C - 查詢表
- C - 點(.)運算子
- C - 列舉(或列舉型別)
- C - 結構體填充和打包
- C - 巢狀結構體
- C - 匿名結構體和聯合體
- C - 聯合體
- C - 位域
- C - Typedef
- C語言中的檔案處理
- C - 輸入與輸出
- C - 檔案I/O(檔案處理)
- C預處理器
- C - 預處理器
- C - 指令
- C - 預處理器運算子
- C - 宏
- C - 標頭檔案
- C語言中的記憶體管理
- C - 記憶體管理
- C - 記憶體地址
- C - 儲存類
- 其他主題
- C - 錯誤處理
- C - 可變引數
- C - 命令執行
- C - 數學函式
- C - static 關鍵字
- C - 隨機數生成
- C - 命令列引數
- C程式設計資源
- C - 問答
- C - 快速指南
- C - 速查表
- C - 有用資源
- C - 討論
C語言中的遞迴
遞迴是指一個函式呼叫自身的過程。C語言允許編寫這樣的函式,這些函式透過將複雜問題分解成簡單易處理的問題來呼叫自身以解決複雜問題。這些函式被稱為遞迴函式。
什麼是C語言中的遞迴函式?
C語言中的遞迴函式是一個函式,它呼叫自身。當某個問題以自身來定義時,就會使用遞迴函式。雖然它涉及迭代,但使用迭代方法來解決此類問題可能會很繁瑣。遞迴方法為看似複雜的問題提供了一種非常簡潔的解決方案。
語法
一個通用的遞迴函式看起來像這樣:
void recursive_function(){ recursion(); // function calls itself } int main(){ recursive_function(); }
在使用遞迴時,程式設計師需要注意定義函式的退出條件,否則它將進入無限迴圈。
為什麼在C語言中使用遞迴?
遞迴用於執行復雜的任務,例如樹和圖結構遍歷。流行的遞迴程式設計解決方案包括階乘、二分查詢、樹遍歷、漢諾塔、國際象棋中的八皇后問題等。
遞迴程式變得簡潔,但不容易理解。即使程式碼的大小可能減少,它也需要更多處理器資源,因為它涉及對函式的多次IO呼叫。
使用遞迴計算階乘
遞迴函式對於解決許多數學問題非常有用,例如計算數字的階乘、生成斐波那契數列等。
遞迴最流行的例子是階乘的計算。在數學上,階乘定義為:
n! = n X (n-1)!
可以看出,我們使用階乘本身來定義階乘。因此,這是一個適合編寫遞迴函式的案例。讓我們擴充套件上述定義來計算5的階乘值。
5! = 5 X 4! 5 X 4 X 3! 5 X 4 X 3 X 2! 5 X 4 X 3 X 2 X 1! 5 X 4 X 3 X 2 X 1 = 120
雖然我們可以使用迴圈執行此計算,但它的遞迴函式涉及透過遞減數字來連續呼叫自身,直到它達到1。
示例:非遞迴階乘函式
以下程式演示瞭如何使用非遞迴函式來計算數字的階乘:
#include <stdio.h> #include <math.h> // function declaration int factorial(int); int main(){ int a = 5; int f = factorial(a); printf("a: %d \n", a); printf("Factorial of a: %d", f); } int factorial(int x){ int i; int f = 1; for (i = 5; i >= 1; i--){ f *= i; } return f; }
輸出
執行此程式碼時,它將產生以下輸出:
a: 5 Factorial of a: 120
示例:遞迴階乘函式
現在讓我們為計算給定數字的階乘編寫一個遞迴函式。
以下示例使用遞迴函式計算給定數字的階乘:
#include <stdio.h> #include <math.h> /* function declaration */ int factorial(int i){ if(i <= 1){ return 1; } return i * factorial(i - 1); } int main(){ int a = 5; int f = factorial(a); printf("a: %d \n", a); printf("Factorial of a: %d", f); return 0; }
輸出
執行程式碼並檢查其輸出:
a: 5 Factorial of a: 120
當main()函式透過傳遞變數“a”來呼叫factorial()函式時,它的值將儲存在“i”中。factorial()函式連續呼叫自身。
在每次呼叫中,"i"的值在減少1後乘以其先前值,直到它達到1。當它達到1時,從引數的初始值到1之間所有值的乘積將返回到main()函式。
使用遞迴進行二分查詢
讓我們再看一個例子來了解遞迴是如何工作的。手頭的問題是在陣列中檢查給定數字是否存在。
雖然我們可以使用for迴圈並比較每個數字來對列表中的某個數字進行順序查詢,但順序查詢效率不高,尤其是在列表過長的情況下。
二分查詢演算法檢查索引“start”是否大於索引“end”。根據變數“mid”處的值,再次呼叫該函式以搜尋元素。
我們有一個按升序排列的數字列表。然後我們找到列表的中點,並將檢查限制在中點的左側或右側,具體取決於所需數字是否小於或大於中點處的數字。
示例:遞迴二分查詢
以下程式碼實現了遞迴二分查詢技術:
#include <stdio.h> int bSearch(int array[], int start, int end, int element){ if (end >= start){ int mid = start + (end - start ) / 2; if (array[mid] == element) return mid; if (array[mid] > element) return bSearch(array, start, mid-1, element); return bSearch(array, mid+1, end, element); } return -1; } int main(void){ int array[] = {5, 12, 23, 45, 49, 67, 71, 77, 82}; int n = 9; int element = 67; int index = bSearch(array, 0, n-1, element); if(index == -1 ){ printf("Element not found in the array "); } else{ printf("Element found at index: %d", index); } return 0; }
輸出
執行程式碼並檢查其輸出:
Element found at index: 5
使用遞迴生成斐波那契數列
在斐波那契數列中,一個數字是其前兩個數字的和。要生成斐波那契數列,第i個數字是i-1和i-2的加和。
示例
以下示例使用遞迴函式為給定數字生成斐波那契數列的前10個數字:
#include <stdio.h> int fibonacci(int i){ if(i == 0){ return 0; } if(i == 1){ return 1; } return fibonacci(i-1) + fibonacci(i-2); } int main(){ int i; for (i = 0; i < 10; i++){ printf("%d\t\n", fibonacci(i)); } return 0; }
輸出
編譯並執行上述程式碼時,將產生以下結果:
0 1 1 2 3 5 8 13 21 34
在程式中實現遞迴對於初學者來說比較困難。雖然任何迭代過程都可以轉換為遞迴過程,但並非所有遞迴案例都可以輕鬆地迭代表示。