4.函数的递归
什么是递归?
程序调用自身的编程技巧称为递归( recursion)。 递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接 调用自身的 一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解, 递归策略 只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
递归的主要思考方式在于:把大事化小
递归的必要条件
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2.每次递归调用之后越来越接近这个限制条件。
递归练习
顺序打印
接受一个整型值(无符号),按照顺序打印它的每一位。
例如: 输入:1234,输出 1 2 3 4.
#include <stdio.h>
void print(int n) //设置一个打印函数
{
if(n>9)
{
print(n/10);
}
printf("%d ", n%10);
}
int main()
{
int num = 1234;
print(num); //递归
return 0;
}
求字符串的长度。
编写函数不允许创建临时变量,求字符串的长度。
#incude <stdio.h>
int Strlen(const char*str)
{
if(*str == '\0')
return 0;
else
return 1+Strlen(str+1);
}
int main()
{
char *p = "abcdef";
int len = Strlen(p);
printf("%d\n", len);
return 0;
}
求n的阶乘。
利用递归方法,求n的阶乘。
int factorial(int n)
{
if(n <= 1)
return 1;
else
return n * factorial(n-1);
}
5.经典递归题
汉诺塔问题
汉诺塔问题源自印度一个古老的传说,印度教的“创造之神”梵天创造世界时做了 3 根金刚石柱,其中的一根柱子上按照从小到大的顺序摞着 64 个黄金圆盘。梵天命令一个叫婆罗门的门徒将所有的圆盘移动到另一个柱子上,移动过程中必须遵守以下规则:
● 每次只能移动柱子最顶端的一个圆盘;
● 每个柱子上,小圆盘永远要位于大圆盘之上;
#include <stdio.h>
void hanoi(int num, char sou, char tar,char aux) {
//统计移动次数
static int i = 1;
//如果圆盘数量仅有 1 个,则直接从起始柱移动到目标柱
if (num == 1) {
printf("第%d次:从 %c 移动至 %c\n", i, sou, tar);
i++;
}
else {
//递归调用 hanoi() 函数,将 num-1 个圆盘从起始柱移动到辅助柱上
hanoi(num - 1, sou, aux, tar);
//将起始柱上剩余的最后一个大圆盘移动到目标柱上
printf("第%d次:从 %c 移动至 %c\n", i, sou, tar);
i++;
//递归调用 hanoi() 函数,将辅助柱上的 num-1 圆盘移动到目标柱上
hanoi(num - 1, aux, tar, sou);
}
}
青蛙跳台阶
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
#include<stdio.h>
int jump(int n)
{
if (n == 1)
{
return 1;
}
else
{
return 2 * jump(n - 1);
}
}
int main()
{
int num = 0;
printf("请输入一个台阶数:> ");
scanf_s("%d", &num);
int ret = jump(num);
printf("小青蛙有 %d种 跳法\n", ret);
return 0;
}