非递归也就是我们俗称的循环,非递归代码可能很长,但成本低(包括运行时间等)
递归也就是俗称的自己调用自己,代码或许很短,但成本高
两种各有利弊,大多可以相互转换,但有些情况,非一种不可
例题如下:
1.递归和非递归分别实现求第n个斐波那契数
#include
int fib1(int n)//非递归
{
int i;
int f1 = 1;
int f2 = 1;
int f3 = 0;
for (i = 2; i < n; i++)
{
//循环赋值
f3 = f1 + f2;
f1 = f2;
f2 = f3;
}
return f3;
}
int fib2(n)//递归
{
if (n <= 2)
{
return 1;
}
else
{
return fib2(n - 1) + fib2(n - 2);
}
}
int main()
{
int n=0;
int ret1;
int ret2;
scanf("%d",&n);
ret1 = fib1(n);
printf("非递归=%d\n",ret1);
ret2 = fib2(n);
printf("递归=%d\n",ret2);
return 0;
}
2.编写一个函数实现n^k,使用递归实现
#include
int fac(int n,int k)//递归
{
if (0 == k)
return 1;
else if (1 == k)
return n;
else if (k > 1)
return n*fac(n, k - 1);
else
return -1;
}
int main()
{
int n, k;
int ret;
printf("输入一个数字和需要计算的幂次:");
scanf("%d%d",&n,&k);
if (-1 == ret)
printf("输入错误!\n");
else
ret = fac(n, k);
printf("%d",ret);
return 0;
}
3.. 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和,例如,调用DigitSum(1729),则应该返回1 + 7 + 2 + 9,它的和是19
#include
int DigitSum(int n)
{
if (n < 10)
{
return n;
}
else
{
return DigitSum(n / 10) + n % 10;
}
}
int main()
{
int n,i=0;
printf("请输入一个非负整数:\n");
scanf("%d",&n);
int ret = DigitSum(n);
printf("%d",ret);
return 0;
}
4.递归和非递归分别实现strlen
#include
int MyStrlen1(char arr[])//非递归//*str
{
int i=0;
while (arr[i]!=0)
{
i++;
}
return i;
}
int MyStrlen2(char arr[])//递归
{
int i = 0;
if (arr[i] != 0)//*str !='\0'
return 1 + MyStrlen2(arr+1);
else
return 0;
}
int main()
{
char arr[] ="hello world!";//或者char *str="hello world!";
int count1 = MyStrlen1(arr);//(str)
printf("非递归=%d\n",count1);
int count2 = MyStrlen2(arr);
printf("递归=%d\n",count2);
return 0;
}
5.递归和非递归分别实现求n的阶乘
#include
int Fac1(int n)//非递归
{
int i;
int sum = 1;
if (0 == n)
return 1;
else
{
for (i = 1; i <= n; i++)
{
sum *= i;
}
return sum;
}
}
int Fac2(int n)//递归
{
if (0 == n)
return 1;
else
return n*Fac2(n - 1);
}
int main()
{
int n,ret1;
printf("请输入需要阶乘的整数:\n");
scanf("%d",&n);
if (n < 0)//提前判断是否符合
{
printf("输入错误!\n");
}
else
{
ret1 = Fac1(n);
printf("非递归=%d\n", ret1);
int ret2 = Fac2(n);
printf("递归=%d\n", ret2);
}
return 0;
}
6.递归方式实现打印一个整数的每一位
#include
void output(int x)
{
if (x >= 10)
{
output(x / 10); //x=x/10也对
}
printf("%d ", x % 10);
}
int main()
{
int a;
printf("请输出一个数");
scanf("%d", &a);
output(a);
return 0;
}
7.编写一个函数 reverse_string(char * string)(递归和非递归实现)实现:将参数字符串中的字符反向排列。
#include
#include
void reverse_string1(char *p)
{
int len = strlen(p);//字符串长度
char tmp = *p;
*p = *(p + len - 1);
*(p + len - 1) = '\0';
if (strlen(p + 1) > 1)
{
reverse_string1(p + 1);
}
*(p + len - 1) = tmp;
}
void reverse_string2(char* str)
{
char *left = str;
char *right = str + strlen(str) - 1;
char temp;
while (left <= right)
{
temp = *left;
*left=*right;
*right=temp;
right--;
left++;
}
}
int main()
{
char str[] = "hello world!";
printf("初始化=%s\n", str);
reverse_string1(str);
printf("递归逆序=%s\n", str);
reverse_string2(str);
printf("非递归再逆序=%s\n",str);
return 0;
}
8.汉诺塔问题(递归)
#include
void move(char pos1, char pos2)//移动步骤函数
{
printf("%c-->%c\n",pos1,pos2);
}
void Hanoi(int n, char pos1,char pos2,char pos3)
{
if (n == 1)
{
move(pos1,pos3);//递归出口
}
else
{
Hanoi(n - 1, pos1, pos3, pos2);
move(pos1,pos3);
Hanoi(n-1,pos2,pos1,pos3);
}
}
int main()
{
int n;
printf("请输入汉诺塔盘子数:");
scanf("%d\n",&n);
Hanoi(n,'A','B','C');
return 0;
}