c語言遞歸系列總結

遞歸

什麼是遞歸

遞歸簡而言之就是函數自己調用自己 如圖所示
在這裏插入圖片描述
但是遞歸併不是簡簡單單的自己調用自己的過程 它分爲 傳遞迴歸,傳遞就是橙色箭頭 迴歸則是黑色箭頭 這就是遞歸
以 計算階乘爲例,假設我們輸入6 計算6的階乘爲例


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int factorial(int x) //遞歸體函數
{
   
   
	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;
}

具體實現過程如下 我們可以很清楚看到 先傳遞 在歸一 就是遞歸
在這裏插入圖片描述

遞歸的特點 結構 缺點

在這裏插入圖片描述

遞歸的本質

在傳遞的過程將問題化簡 歸一的過程將化簡的問題解決

遞歸的應用

(1). 問題的定義是按遞歸定義的(Fibonacci函數,階乘,…);

(2). 問題的解法是遞歸的(有些問題只能使用遞歸方法來解決,例如,漢諾塔問題,…);

(3). 數據結構是遞歸的(鏈表、樹等的操作,包括樹的遍歷,樹的深度,…)

遞歸實戰

階乘

階乘遞歸解法

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int factorial(int x)   // 遞歸體
{
   
   
	if (x == 1)// 函數出口
	{
   
   
		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;    //利用循環累乘 最後打印
	}
	printf("%d", sum);
	return 0;
}

斐波拉契數列

斐波拉契數列 即0、1、1、2、3、5、8、13、21、34、………這樣一串數字
在這裏插入圖片描述

斐波拉契數列遞歸解法

遞歸解法通過數學函數定義可輕鬆得到 他的遞歸體
是當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); //循環體 
}


int main()
{
   
   
	int k = 0;
	scanf("%d", &k);
	int sum = fib(k);
	printf("%d", sum);
	return 0;
}

斐波拉契數列普通解法

#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;
}

漢諾塔

漢諾塔簡單瞭解

輸出一個數字的每一位

如 輸入 1234 輸出 1 2 3 4

普通解法

這裏用取對數的方法得到有多少位 依次除以位數的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;
}

倒序保存字符串

將參數字符串中的字符反向排列,不是逆序打印

遞歸解法

#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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章