C語言遞歸系列的深入總結(jié)
遞歸
什么是遞歸
遞歸簡(jiǎn)而言之就是函數(shù)自己調(diào)用自己 如圖所示

但是遞歸并不是簡(jiǎn)簡(jiǎn)單單的自己調(diào)用自己的過程 它分為 傳遞 和 回歸,傳遞就是橙色箭頭 回歸則是黑色箭頭 這就是遞歸
以 計(jì)算階乘為例,假設(shè)我們輸入6 計(jì)算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;
}
具體實(shí)現(xiàn)過程如下 我們可以很清楚看到 先傳遞 在歸一 就是遞歸

遞歸的特點(diǎn) 結(jié)構(gòu) 缺點(diǎn)

遞歸的本質(zhì)
在傳遞的過程將問題化簡(jiǎn) 歸一的過程將化簡(jiǎn)的問題解決
遞歸的應(yīng)用
(1). 問題的定義是按遞歸定義的(Fibonacci函數(shù),階乘,…);
(2). 問題的解法是遞歸的(有些問題只能使用遞歸方法來解決,例如,漢諾塔問題,…);
(3). 數(shù)據(jù)結(jié)構(gòu)是遞歸的(鏈表、樹等的操作,包括樹的遍歷,樹的深度,…)
遞歸實(shí)戰(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!轉(zhuǎn)換成X*((x-1)!) 達(dá)到傳遞化簡(jiǎn)的目的
}
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、………這樣一串?dāng)?shù)字

斐波拉契數(shù)列遞歸解法
遞歸解法通過數(shù)學(xué)函數(shù)定義可輕松得到 他的遞歸體
是當(dāng)n>1時(shí) 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個(gè)元素為0 第一個(gè)元素為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;
}
漢諾塔
輸出一個(gè)數(shù)字的每一位
如 輸入 1234 輸出 1 2 3 4
普通解法
這里用取對(duì)數(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); //將最后一個(gè)和第一個(gè)互換
*(arr + sz - 1) = '\0';// 將最后一個(gè)賦值為0
if (strlen(arr) > 1)//如果不是最后一個(gè)則 指針后移
{
reverse_string(arr + 1);
}
*(arr + sz - 1) = tmp;
}
int main()
{
char arr[] = "abcdef";
reverse_string(arr);
printf("%s\n", arr);
}
總結(jié)
到此這篇關(guān)于C語言遞歸系列的文章就介紹到這了,更多相關(guān)C語言遞歸內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用VSCode和VS2017編譯調(diào)試STM32程序的實(shí)現(xiàn)
這篇文章主要介紹了使用VSCode和VS2017編譯調(diào)試STM32程序的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
Visual Studio中scanf函數(shù)報(bào)錯(cuò)的幾種解決方法
本文主要介紹了Visual Studio中scanf函數(shù)報(bào)錯(cuò)的幾種解決方法,文中通過圖文示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03
Qt6.0+vs2019環(huán)境配置的實(shí)現(xiàn)教程
這篇文章主要介紹了Qt6.0+vs2019環(huán)境配置的實(shí)現(xiàn)教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
C++小利器之std::bind參數(shù)綁定包裝器的使用詳解
從 C++11 開始,標(biāo)準(zhǔn)庫(kù)提供了 std::bind 用于綁定函數(shù) f 和調(diào)用參數(shù),返回一個(gè)新可調(diào)用函數(shù)對(duì)象 fn,下面就跟隨小編一起深入了解一下std::bind的具體使用吧2023-12-12

