递归
一、概念:程序调用自身。
二、思想:将大化小。
三、使用必要条件:
1、处理问题的子问题可以被相同的逻辑处理;
2、存在递归出口;
3、每次调用自身之后越来越接近此递归出口。
四、优缺点:
优:便于理解、代码小;
缺:开销大、性能低(程序调用自身,自身也为函数,调用函数则要建立栈帧,释放栈帧)
总:基于此,在问题过于复杂时,递归的简洁性可以补偿它的开销;至于遇到问题使用什么算法,还是看情况而定。
五、几个递归练习以及与非递归的比较
1.递归和非递归分别实现求第n个斐波那契数;
2.编写一个函数实现n^k,使用递归实现;
3.写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和;
4. 编写一个函数reverse_string(char * string)(递归实现)
实现:将参数字符串中的字符反向排列、要求:不能使用C函数库中的字符串操作函数;
5.递归和非递归分别实现strlen;
6.递归和非递归分别实现求n的阶乘;
7.递归方式实现打印一个整数的每一位。
#include<stdio.h>
#include<Windows.h>
//斐波那契数列(递归)
int fib_r(int n)
{
if (n == 1 || n == 2){
return 1;
}
return fib_r(n - 1) + fib_r(n - 2);
}
//斐波那契数列(迭代)
int fib_i(int n)
{
int first = 1;
int second = 1;
int sum = 1;
int i = 1;
while (i <= n - 2){
sum = first + second;
first = second;
second = sum;
i++;
}
return sum;
}
//n^k(递归)
int power_r(int n, int k)
{
if (k == 1){
return n;
}
return n*power_r(n, k - 1);
}
//n^k(迭代)
int power_n(int n, int k)
{
int res = 1;
while (k){
res *= n;
k--;
}
return res;
}
//求整型各个位数之和(递归)
//n:1826 sum += 6
//n:182 sum += 2
//n:18 sum += 8
//n:1 sum += 1
//先下后上
int digitSum(int n)
{
/*int sum = 0;
if (n){
sum += n % 10 + digitSum(n / 10);
}
return sum;*/
//不创建临时变量
if (n < 10){
return n;
}
return digitSum(n / 10) + n % 10;
}
//字符串反转(递归)
//str = ello *(str-1) = h
//str = llo *(str-1) = e
//str = lo *(str-1) = l
//str = o *(str-1) = l
//str = '\0' *(str-1) = o
//先下后上
void reverse_string(const char * str)
{
if (*(++str)){
reverse_string(str);
}
printf("%c", *(str - 1));//跳过'\0'
}
//字符串反转存入数组中
void reverse_string2(const char *str, char *buf, int *i)
{
if (*(++str)){
reverse_string2(str, buf, i);
}
buf[(*i)++] = *(str - 1);
}
//求字符串长度(递归)
int myStrlen_r(const char * str)
{
if (!*str){
return 0;//不包括'\0'
}
return 1 + myStrlen_r(str + 1);
}
//求字符串长度(迭代)
int myStrlen_n(const char * str)
{
int i = 0;
while (*str){
str += 1;
i++;
}
return i;
}
//n的阶乘(递归)
int factorial_r(int n)
{
if (n == 1){
return 1;
}
return n*factorial_r(n - 1);
}
//n的阶乘(迭代)
int factorial_n(int n)
{
int res = 1;
while (n){
res *= n;
n--;
}
return res;
}
//打印整数的每一位(递归)
void printIntBit(int n)
{
if (n > 9){
printIntBit(n / 10);
}
//执行到这里说明:if条件不满足或递归开始返回
printf("%d ", n % 10);
}
int main()
{
/*printf("%d\n", fib_r(10));
printf("%d\n", fib_i(10));*/
/*printf("%d\n", power_r(8, 5));
printf("%d\n", power_n(8, 5));*/
//printf("%d\n", digitSum(1826));
//reverse_string("hello");
char buf[64];
int i = 0;
reverse_string2("hello", buf, &i);
buf[i] = '\0';
/*printf("%d\n", myStrlen_r("hello!"));
printf("%d\n", myStrlen_n("hello!"));*/
/*printf("%d\n", factorial_r(3));
printf("%d\n", factorial_n(3));*/
//printIntBit(167);
system("pause");
return 0;
}