一、概念
程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。递归需要满足以下两个条件:
- 子问题须与原始问题为同样的事,且更为简单;
- 不能无限制地调用本身,须有个条件限制,结束递归调用
递归优缺点明显
优点: 结构清晰, 可读性强
缺点:
- 递归是函数调用自身,函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址以及临时变量,而往栈中压入数据和弹出数据都需要时间。->效率
- 递归中很多计算都是重复的,由于其本质是把一个问题分解成两个或者多个小问题,多个小问题存在相互重叠的部分,则存在重复计算,如fibonacci斐波那契数列的递归实现。->效率
- 调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出。->性能
详情见:https://blog.csdn.net/wangzhenling/article/details/59702845
二、具体解决问题
1、字符串逆序
/*************************************************************************************************************
输入参数: 需要逆序的字符串
功能: 将输入的字符串逆序输出
注释: 通过递归调用, 直到指针指向支付串末尾‘\0’, 开始输出
*******************************************************************************************************/
void recursion_char(char *c)
{
if(*c)
{
recursion_char(c+1);
printf("%c", *c);
}
}
首先我们先建立一个字符数组str[100],即字符串用于存放输入的字符,假如我们输入hello,则此时的数组名str指向的是此时的数组头部,即h(如下图)
需要逆序输出字符串, 则需将str指向最后一位,再往前移动输出字符, 如何将str指向最后一位呢? 因为输出字符长度是不固定的, 但是有一个共同特点, 就是都是以’\0’结尾, 所以我们只需每次将指针往后挪一位,这符合了我们的第一个条件:子问题须与原始问题为同样的事;
再判断其是否等于‘\0’字符即可,这也满足了我们的第二个条件,不能无限制地调用本身,须有个条件限制,结束递归调用。
所以我们每次都调用函数recursion_char( ),将指针str+1, 直到找到尾部,再依次打印
2、整数逆序
/*************************************************************************************************************
输入参数: 需要逆序的整数
功能: 将输入的整数逆序输出
注释: 首先判断此时整数变量的位数, 只有一位直接输出, 不止一位, 将其最后一位取出输出,递归求值。
*************************************************************************************************************/
void recursion_int(int n)
{
if(n<10)
{
printf("%d", n);
return ;
}
printf("%d", n%10);
recursion_int(n/10);
}
整数逆序, 因为是十进制, 我们每次通过与10取余取出最右边一位, 再利用整形的自动取整功能, 除以10减去最右边一位。
3.例程
#include <stdio.h>
#include <stdlib.h>
/*************************************************************************************************************
输入参数: 需要逆序的整数
功能: 将输入的整数逆序输出
注释: 首先判断此时整数变量的位数, 只有一位直接输出, 不止一位, 将其最后一位取出输出,递归求值。
*************************************************************************************************************/
void recursion_int(int n)
{
if(n<10)
{
printf("%d", n);
return ;
}
printf("%d", n%10);
recursion_int(n/10);
}
/*************************************************************************************************************
输入参数: 需要逆序的字符串
功能: 将输入的字符串逆序输出
注释: 通过递归调用, 直到指针指向支付串末尾‘\0’, 开始输出
*******************************************************************************************************/
void recursion_char(char *c)
{
if(*c)
{
recursion_char(c+1);
printf("%c", *c);
}
}
int main()
{
int num, cmd;
char str[100];
while(1)
{
printf("***********************************************************************************\n");
printf("请选择功能:\n");
printf("1、整数逆序 2、字符逆序 3、退出\n");
printf("***********************************************************************************\n");
scanf("%d", &cmd);
switch(cmd)
{
case 1:
{
printf("请输入一个整数,以回车结束:\t");
scanf("%d", &num);
printf("整数逆序结果是:\t");
recursion_int(num);
printf("\n");
break;
}
case 2:
{
printf("请输入一个字符串, 以回车结束:\t");
scanf("%s", str);
printf("字符串逆序结果是:\t");
recursion_char(str);
printf("\n");
break;
}
case 3:
printf("再见!\n");
exit(0);
default:
printf("输入有误, 请重新输入!\n");
break;
}
}
return 0;
}