日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

对于C语言函数递归的简单理解(新手入门必看!!!)

發布時間:2024/3/26 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对于C语言函数递归的简单理解(新手入门必看!!!) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是函數遞歸?

程序調用自身的編程技巧稱為遞歸(recursion)。 遞歸做為一種算法在程序設計語言中廣泛應用。 一個過程或函數在其定義或說明中有直接或間接 調用自身的 一種方法,它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞歸策略: 只需少量的程序就可描述出解題過程所需要的多次重復計算,大大地減少了程序的代碼量。 遞歸的主要思考方式在于:把大事化小 遞歸顧名思義也可以這樣理解:遞送與回歸。 這里引用站上一位大佬的話: 我覺得特別貼切 “遞歸:你打開面前這扇門,看到屋里面還有一扇門。你走過去,發現手中的鑰匙還可以打開它,你推開門,發現里面還有一扇門,你繼續打開它。若干次之后,你打開面前的門后,發現只有一間屋子,沒有門了。然后,你開始原路返回,每走回一間屋子,你數一次,走到入口的時候,你可以回答出你到底用這你把鑰匙打開了幾扇門。

   循環:你打開面前這扇門,看到屋里面還有一扇門。你走過去,發現手中的鑰匙還可以打開它,你推開門,發現里面還有一扇門(若前面兩扇門都一樣,那么這扇門和前兩扇門也一樣;如果第二扇門比第一扇門小,那么這扇門也比第二扇門小,你繼續打開這扇門,一直這樣繼續下去直到打開所有的門。但是,入口處的人始終等不到你回去告訴他答案。”

再放一個通俗易懂的列子,幫助大家更好的理解遞歸:

我需要打開快遞包裝,于是買了個剪刀。但是剪刀也有包裝,所以我又買了一個剪刀,這個剪刀上又有包裝,所以我又買了個剪刀。。。
最后我沒錢了,于是我用牙撕開了最后一個剪刀的包裝,然后用這個剪刀打開了倒數第二個簡單的包裝,然后。。。最后用第一個剪刀打開了快遞的包裝,拿出了東西。
這個沙雕的過程就叫遞歸,遞歸必須要有停止條件(例子中是我把錢花完),要不然你就會擁有無數的剪刀,但又打不開快遞(忘了目的系列)。
?

下面放幾個簡單的程序來進行遞歸的理解與使用。 1.接受一個整型值(無符號),按照順序打印它的每一位。 void print(unsigned int n) // n=1234 {if (n > 9){print(n / 10); //123 12 1}printf("%d ", n % 10); 1 2 3 4 }int main() {unsigned int num = 0;scanf("%u", &num);print(num);return 0; }

2.編寫函數不允許創建臨時變量,求字符串的長度。

int my_strlen(char* s) {if (*s != '\0'){return 1 + my_strlen(s + 1);}else{return 0;} }int main() {char arr[10] = { "abcdaaaa" };int len = my_strlen(arr);printf("%d\n", len);return 0; }

3.求n的階乘。

int Fac(int n) {if (n <= 1){return 1;}else{return n*Fac(n - 1);} } int main() {int n = 0;scanf("%d", &n);int ret = Fac(n);printf("%d\n", ret);return 0; }

4.求斐波那契數列底n個數的值。

int Fib(int n) {if (n <= 2)return 1;elsereturn Fib(n - 1) + Fib(n - 2); }int main() {int n = 0;scanf("%d", &n);int ret = Fib(n);printf("%d\n", ret);return 0; }

?5.字符串逆序(遞歸實現)【將參數字符串中的字符反向排列,不是逆序打印。】

思路:

逆置字符串,循環的方式實現非常簡單

? 1. 給兩個指針,left放在字符串左側,right放在最后一個有效字符位置

? 2. 交換兩個指針位置上的字符

? 3. left指針往后走,right指針往前走,只要兩個指針沒有相遇,繼續2,兩個指針相遇后,逆置結束

#include <stdio.h> void reverse_string(char* arr) {int len = strlen(arr);char tmp = *arr;*arr = *(arr + len - 1);*(arr + len - 1) = '\0';if (strlen(arr+1)>=2)reverse_string(arr + 1);*(arr + len - 1) = tmp; } /*或者不用指針表示: int my_string(char* str) {int count = 0;while (*str != '\0'){count++;str++;}return count; }void reverse_string(char str[]) {int len = my_string(str);int tmp = str[0];str[0] = str[len - 1];str[len - 1] = '\0';if (my_string(str + 1) >= 2){reverse_string(str + 1);}str[len - 1] = tmp; } */ int main() {char arr[] = { "abc" };reverse_string(arr);printf("%s", arr); }

6.計算一個數的每位之和(遞歸實現)

#include <stdio.h> int DigitSum(int n) {if (n > 9){return DigitSum(n / 10) + n % 10;}elsereturn n; }int main() {int n = 0;scanf("%d", &n);int ret = DigitSum(n);printf("%d\n", ret); }

7.遞歸實現n的k次方?

#include <stdio.h> int pow(int n, int k) {if (k == 0)return 1;else if (k >= 1)return n*pow(n, k - 1); } int main() {int n = 0;int k = 0;scanf("%d %d", &n, &k);int ret = pow(n, k);printf("%d\n", ret);return 0; }

8.? 求 1+2+3....+n 的值 。

#include <stdio.h> int sum(int n) {if (n == 1)return 1; // 出口 (必要的)elsereturn (sum(n - 1) + n); //根據表達式 F(n)=f(n-1)+n 取等號后邊式子 稱為 遞推關系式 } int main() {int n = 0;scanf("%d", &n);int ret = sum(n);printf("%d\n", ret);/*int num = sum(100);printf("%d\n", num);*/return 0; }

9. 已知一個整形數組,求出前n項數字之和。

#include <stdio.h> int sum(int arr[], int n) {if (n == 0)return arr[0];elsereturn sum(arr, n - 1) + arr[n]; } int main() {int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int ret = sum(arr, 4);printf("%d\n", ret);return 0; }

10.??求一個已知數組里面前n個數字里面的最大值 (下標為n計算)

#include <stdio.h> int max(int arr[], int n) {if (n == 0)return arr[0];else if (max(arr, n - 1) > arr[n])return max(arr, n - 1);elsereturn arr[n]; } int main() {int arr[] = { 7, 4, 8, 6, 3, 2, 9, 11, 5 };int n = 0;scanf("%d", &n);int ret = max(arr, n);printf("%d\n", ret);return 0; }

11.??遞歸中的冒泡排序

void bubble(int arr[], int L, int R) {if (L < R){int i = 0;for (i = L; i <= R - 1; i++){if (arr[i] > arr[i + 1]){int tmp = arr[i];arr[i] = arr[i + 1];arr[i + 1] = tmp;}}bubble(arr, L, R - 1);} } int main() {int i = 0;int arr[7] = { 7, 6, 5, 4, 3, 2, 1 };bubble(arr, 0, 6);for (i = 0; i < 7; i++){printf("%d ", arr[i]);}return 0; }

12.求兩數最大公約數?

int gcd(int a, int b) {if (a%b == 0)return b;else{int r = 0;r = a%b;return gcd(b, r);} } int main() {int a = 0;int b = 0;scanf("%d %d", &a, &b);int ret = gcd(a, b);printf("%d\n", ret); }

總結:

什么時候用遞歸:


1.當解決一個問題遞歸和非遞歸都可以使用,且沒有明顯問題。那就可以使用遞歸。


2.當解決一個問題遞歸寫起來很簡單,非遞歸比較復雜,且遞歸沒有明顯問題,那就用遞歸。

3.如果說用遞歸解決問題,寫起來簡單,但是有明顯問題,那就不能使用遞歸。得寫出非遞歸的方式來解決。

小tips :

?遞歸想的深入了,很容易被繞進去,這時我們就要記住“ 我們是懶懶的老和尚,計算機就是忙碌的小和尚,我們不要管他們。”? 把它想成,在還沒有到達遞歸函數出口位置時,在做重復的事情就可以了。既然是重復的事情就沒有必要每一樣都去驗證了 。

總結

以上是生活随笔為你收集整理的对于C语言函数递归的简单理解(新手入门必看!!!)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。