看完這篇文章小白也能一次性搞得懂遞歸問題!!!

Hello everyone 我是Bladcub~

歡迎再次來到我的“一週一篇小博客“的專題欄目

-----我剛學習了函數遞歸 ,一開始也很是不懂 然後練習了很多題後 有所感悟, 在此和大家分享交流學習!!! 若有不妥的地方請大神指點一二 !!!萬分感謝!!!

劃重點:此次內容較長 !

第一步 瞭解函數遞歸

  1. 遞歸的定義:
    一種計算過程,如果其中每一步都要用到前一步或前幾步的結果,稱爲遞歸的。用遞歸過程定義的函數,稱爲遞歸函數,例如連加、連乘及階乘等。凡是遞歸的函數,都是可計算的,即能行的 。(來自百度百科)

  2. 遞歸是什麼?
    用編程技巧通常把一個大型復 雜的問題層層轉化爲一個與原問題相似的規模較小的問題來求解,用少量的程序描述出複雜的解題過程,減少程序的代碼量。

  3. 遞歸的兩個必要條件
    —存在限制條件,當滿足這個限制條件的時候,遞歸便不再繼續。
    —每次遞歸調用之後越來越接近這個限制條件

第二步 直接上代碼感受(建議練習)

  1. 遞歸方式實現打印一個整數的每一位
#include<stdio.h>
void recur(int n)
{
   
   
	if (n / 10 == 0)    
	{
   
   
		printf("%d ", n);
	}
	else 
	{
   
   
		recur(n / 10);
		printf("%d ", n%10);
	}
}
int main()
{
   
   
	int n = 0;
	printf("請輸入你要打印的整數:");
	scanf("%d", &n);
	recur(n);
	return 0;
}
  1. 實現求n的階乘(不考慮溢出的問題)
    首先是遞歸方法:
#include<stdio.h>
int  fac(int n)
{
   
   
	if (n < 2)
	{
   
   
		return 1;
	}
	else
	{
   
   
		n = n*fac(n - 1);
		return n;
	}
}
int main()
{
   
   
	int n = 0;
	printf("請輸入你的數字:\n");
	scanf("%d", &n);
	fac(n);
	printf("他的階乘爲:%d\n", fac(n));
	return 0;
}

然後放一個非遞歸方法 大家感受一下不同:

#include<stdio.h>
int fac(int N)
{
   
   
	int ret = 1;
	for (int i = 2; i <= N; i++)
	{
   
   
		ret *= i;
	}

	return ret;
}
int main()
{
   
   
	int n = 0;
	printf("請輸入你的數字:\n");
	scanf("%d", &n);
	fac(n);
	printf("他的階乘爲:%d\n",fac(n));
	return 0;
}
  1. 求字符串長度
    遞歸:
#include<stdio.h>
int my_strlen(char *arr)
{
   
   
	if (*arr != '\0')
	{
   
   
		return 1 + my_strlen(arr + 1);
	}
	else
	{
   
   
		return 0;
	}
}
int main()
{
   
   
	char arr[] = "hello world";
	my_strlen(arr);
	printf("字符串的長度爲:%d\n", my_strlen(arr));
}

非遞歸:

#include<stdio.h>
int my_strlen(char *arr)
{
   
   
	int count = 0;
	while(*arr != '\0')
	{
   
   
		arr++;
		count++;
	}
	return count;
}
int main()
{
   
   
	char arr[] = "hello world";
	my_strlen(arr);
	printf("字符串的長度爲:%d\n", my_strlen(arr));
}
  1. 編寫一個函數 reverse_string(char * string)(遞歸實現)
    實現:將參數字符串中的字符反向排列,不是逆序打印。
    要求:不能使用C函數庫中的字符串操作函數。

#include<stdio.h>
void reverse_string(char * string)
{
   
   
	if (*string != '\0')
	{
   
   
		reverse_string(string + 1);
	}
	else
	{
   
   
		printf("%c", *string);
	}
	printf("%c", *string);
}
int main()
{
   
   
	char *string = "abcdef";
	reverse_string(string);
	return 0;
}
  1. 寫一個遞歸函數DigitSum(n),輸入一個非負整數,返回組成它的數字之和
    例如,調用DigitSum(1234),則應該返回1+2+3+4,它的和是10
    輸入:1234,輸出:10

#include<stdio.h>
int DigitSum(int n)
{
   
   
	
	if (n <10)                                      
	{
   
   
		return n;
	}
	else
	{
   
   
		return n % 10 + DigitSum(n / 10);
	}
}
int main()
{
   
   
	int n = 0;
	printf("請輸入你的數字:\n");
	scanf("%d", &n);
	DigitSum(n);
	printf("其返回值爲:%d\n",DigitSum(n));
	return 0;

}
  1. 編寫一個函數實現n的k次方,使用遞歸實現。
#include<stdio.h>
int biqu(int n,int k)
{
   
   
	if (k <= 0)
		return 1;
	else
		return n*biqu(n, k - 1);
}
int main()
{
   
   
	int n = 0;
	int k = 0;
	printf("請輸入你的數字:\n");
	scanf("%d", &n);
	printf("次方數:\n");
	scanf("%d", &k);
	biqu(n,k);
	printf("其k次方結果爲:%d\n", biqu(n,k));
	return 0;
}

  1. 計算斐波那契數
    遞歸:
#include<stdio.h>
int fibo(int n)
{
   
   
	if (n <=2)
	{
   
   
		return 1;
	}
	else
	{
   
   
		return fibo(n - 1) + fibo(n - 2);
	}
}
int main()
{
   
   
	int n = 0;
	printf("你輸入的數");
	scanf("%d", &n);
	fibo(n);
	printf("斐波那契值爲:%d\n", fibo(n));
	return 0;
}

非遞歸:

#include<stdio.h>
int fibo(int n)
{
   
   
	int a = 1;
	int	b = 1;
	int c = 1;

	while (n>2)
	{
   
   
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}
			
int main()
{
   
   
		int n = 0;
		printf("你輸入的數");
		scanf("%d", &n);
		fibo(n);
		printf("斐波那契值爲:%d\n", fibo(n));
		return 0;
}

不知道你細細的看完這些代碼,或者自己實際編寫之後有沒有感覺 遞歸就像是無限月讀 ps:哈哈哈哈資深火影迷, 如果有些代碼不是很明白可以在紙上面寫出他的過程, 慢慢計算感受。 剛開始我也是這樣子的,在這裏說一下我的感受: 一層一層的套進去,然後再一層層的反着再出來。 哈哈哈也不知道這種感受對不對
在這裏插入圖片描述

第三步 更加深入的感受

漢諾塔問題求解:
1.漢諾塔遊戲規則:每次只能移動一個盤子,並且大的盤子不能在小的盤子上面
2.解題步驟:
第一步:
把n-1個模塊 從塔1移動到塔2
把第n個模塊 從塔1移動到塔3
第二步:
把n-1個模塊 從塔2移動到塔3
3.其原理:
要解決n層的漢諾塔
就必須解決n-1層的漢諾塔

必須解決第1層漢諾塔











#include<stdio.h>
int i = 1;//步數
void move(int n, char a, char c)//顯示移動路徑 
{
   
   
	
	printf("第%d步 : 把第%d個盤子從%c--->移動到%c\n", i++, n, a, c);
}

void Hanoi(int n, char a, char b, char c)//遞歸算法 
{
   
   
	if (n == 1) move(n, a, c);  //如果只有一個盤子那麼直接從A柱移到C柱 
	else
	{
   
   
		Hanoi(n - 1, a, c, b);  //把A柱n-1個盤子移到B柱
		move(n, a, c);          //把最後一個盤子從A柱移到C柱 
		Hanoi(n - 1, b, a, c);  //把B柱n-1個盤子移到C柱 
	}
}
int main()
{
   
   
	int m;
	scanf("%d", &m);//輸入盤子的個數 
	Hanoi(m, 'A', 'B', 'C');
	return 0;
}

第四步 總結心得

身爲小白的我還需要多加練習!自己還有許多不懂的地方要多加深入研究,可能此次總結並不是很完美,我以後會多加學習進步的!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章