C語言遞歸系列的深入總結
遞歸
什么是遞歸
遞歸簡而言之就是函數(shù)自己調用自己 如圖所示
但是遞歸并不是簡簡單單的自己調用自己的過程 它分為 傳遞 和 回歸,傳遞就是橙色箭頭 回歸則是黑色箭頭 這就是遞歸
以 計算階乘為例,假設我們輸入6 計算6的階乘為例
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int factorial(int x) //遞歸體函數(shù) { if (x == 1) { return 1; } return x * (factorial(x - 1)); } int main() { int i = 0; scanf("%d", & i); int k = factorial(i); printf("%d", k); return 0; }
具體實現(xiàn)過程如下 我們可以很清楚看到 先傳遞 在歸一 就是遞歸
遞歸的特點 結構 缺點
遞歸的本質
在傳遞的過程將問題化簡 歸一的過程將化簡的問題解決
遞歸的應用
(1). 問題的定義是按遞歸定義的(Fibonacci函數(shù),階乘,…);
(2). 問題的解法是遞歸的(有些問題只能使用遞歸方法來解決,例如,漢諾塔問題,…);
(3). 數(shù)據(jù)結構是遞歸的(鏈表、樹等的操作,包括樹的遍歷,樹的深度,…)
遞歸實戰(zhàn)
階乘
階乘遞歸解法
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int factorial(int x) // 遞歸體 { if (x == 1)// 函數(shù)出口 { return 1; } return x * (factorial(x - 1));//就x!轉換成X*((x-1)!) 達到傳遞化簡的目的 } int main() { int i = 0; scanf("%d", & i); int k = factorial(i); printf("%d", k); return 0; }
階乘普通解法
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { int k = 0; scanf("%d", &k); int i = 0; int sum = 1; for (i = 1; i < k + 1; i++) { sum = sum * i; //利用循環(huán)累乘 最后打印 } printf("%d", sum); return 0; }
斐波拉契數(shù)列
斐波拉契數(shù)列 即0、1、1、2、3、5、8、13、21、34、………這樣一串數(shù)字
斐波拉契數(shù)列遞歸解法
遞歸解法通過數(shù)學函數(shù)定義可輕松得到 他的遞歸體
是當n>1時 fib(n-2)+fib(n-1)
遞歸出口就是n=0 返回0,n=1,返回1
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int fib(int x) //第0個元素為0 第一個元素為1 { if (x == 0) { return 0; } else if (x == 1) //出口 { return 1; } else return fib(x - 2) + fib(x - 1); //循環(huán)體 } int main() { int k = 0; scanf("%d", &k); int sum = fib(k); printf("%d", sum); return 0; }
斐波拉契數(shù)列普通解法
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int fib(int x) { int i = 0; int j = 1; int k = 0; int m = 0; for (m = 0; m < x-1; m++) { k = i + j; i = j; j = k; } return k; } int main() { int k = 0; scanf("%d", &k); int sum = fib(k); printf("%d", sum); return 0; }
漢諾塔
輸出一個數(shù)字的每一位
如 輸入 1234 輸出 1 2 3 4
普通解法
這里用取對數(shù)的方法得到有多少位 依次除以位數(shù)的10次方 即可
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<math.h> void elect(int x) { printf("逆序輸出"); float k = 0.1; int m = 0; do { m = x % 10; k = k * 10; printf("%d是%f位",m,k); x = x / 10; if (x < 9) { k = k * 10; printf("%d是%f位", m, k); break; } } while (1); printf("\n \n"); } void elect2(int x) { printf("順序輸出"); int digit = log10(x) ; int i = 0; int m = 0; for (i = pow(10, digit); i >0; i = i / 10) { m = x / i; printf("%d ", m); x = x % i; } } int main() { int k = 0; scanf("%d", &k); //elect(k); elect2(k); return 0; }
遞歸解法
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> void elect(int x) { if (x > 9) { elect(x / 10); //遞歸體 通過除以10 來使得問題更接近正確答案 } printf("%d ", x % 10);//出口 } int main() { int k = 0; scanf("%d", &k); elect(k); return 0; }
倒序保存字符串
將參數(shù)字符串中的字符反向排列,不是逆序打印
遞歸解法
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<math.h> #include<stdio.h> #include<string.h> void reverse_string(char arr[]) { int sz = strlen(arr); int tmp = *arr; *arr = *(arr + sz - 1); //將最后一個和第一個互換 *(arr + sz - 1) = '\0';// 將最后一個賦值為0 if (strlen(arr) > 1)//如果不是最后一個則 指針后移 { reverse_string(arr + 1); } *(arr + sz - 1) = tmp; } int main() { char arr[] = "abcdef"; reverse_string(arr); printf("%s\n", arr); }
總結
到此這篇關于C語言遞歸系列的文章就介紹到這了,更多相關C語言遞歸內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++ read函數(shù)讀入int整形數(shù)據(jù)
這篇文章主要介紹了C++ read函數(shù)讀入int整形數(shù)據(jù)的相關資料,需要的朋友可以參考下2016-07-07C++11中l(wèi)onglong超長整型和nullptr初始化空指針
本文介紹?C++11?標準中新添加的?long?long?超長整型和?nullptr?初始化空指針,在?C++11?標準下,相比?NULL?和?0,使用?nullptr?初始化空指針可以令我們編寫的程序更加健壯,本文結合示例代碼給大家詳細講解,需要的朋友跟隨小編一起看看吧2022-12-12