递归算法初探

前言

C语言允许函数调用它自己,这种调用过程称为递归。递归有时难以捉摸,有时却很方便实用。
可以使用循环的地方通常都可以使用递归。有时用循环解决的问题比较好,但有时用递归解决问题会更好。递归方案简洁,但效率却没有循环高。

演示递归

阶乘

n! = n * (n-1) * (n-2) * ...* 1(n>0)

下面还是以阶乘为例子,循环写法为:

int factorial(int n)
{
    int product = 0;
    while(n>0){
        product *= n;
        n--;
    }
    return product;
}

用递归实现阶乘:

int factorial(int n)
{
    if(n == 1)//需要一个条件,告诉它何时停止。
        return 1;
    else
      return n * factorial(n - 1);
}

这里要说一下,某个数的阶乘等于起始数乘以比它小一的数的阶乘。例如,factorial(5) 与 5 * factorial(4) 相同。

问题:
既然用递归和循环来计算都可以问题,那么到底应该使用哪一个呢?一般而言,选择循环比较好,首先,每次递归都会创建一组变量,所以递归使用的内存更多,而且每次递归调用都会把创建的一组新变量放在栈中。递归调用的数量受限于内存空间。其次,由于每次函数调用要花费一定的时间,所以递归的执行速度较慢。

递归和倒序计算

下面我们通过一个示例,来演示递归倒序的用法。

#include <stdio.h>

//递归演示
void print_number(int n);
void print_string(const char *str);

int main(int argc, char const *argv[])
{
	print_number(1);	
    //print_string("abcd");
	return 0;
}

//
void print_number(int n)
{
	printf("Up %d: n address  %p\n",n,&n);

	if (n < 5)
		print_number(n+1);

	printf("Drop %d: n address  %p\n",n,&n);

}
//倒序打印字符串
void print_string(const char *str)
{
	if (!*str)
		return ;

	print_string(str + 1);

    putchar(*str);
    printf("\n");

}

输出结果:

在这里插入图片描述
在使用递归函数时,递归函数必须包含能让递归调用停止的语句。通常,递归函数都使用if或者其他等价的测试条件在函数形参等于某特定值时终止递归。

递归的优缺点

递归既有优点也有缺点。优点是递归为某些编程问题提供了最简单的解决方案。缺点是一些递归算法会快速消耗计算机的内存资源。还有一点就是递归不方便阅读与维护。

递归解决爬楼梯的问题

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/*爬楼梯的问题,解决重复计算,采用数据保存方法*/

int helper(int n ,int *vlaue);
int helper(int n ,int *vlaue);

int main(int argc, char const *argv[])
{

	printf("\r\nvalue%d ,%d",2,climb_staris(2));
	printf("\r\nvalue%d ,%d",3,climb_staris(3));
	printf("\r\nvalue%d ,%d",4,climb_staris(4));
	printf("\r\nvalue%d ,%d",5,climb_staris(5));
	printf("\n");
	return 0;
}

int helper(int n ,int *vlaue)
{

    if(vlaue[n] != 0)
	{
		return vlaue[n];
	}

    vlaue[n] = helper(n - 1,vlaue) + helper(n - 2,vlaue);//使用双递归

	return vlaue[n];
}

int climb_staris(int n)
{
	int *vlaue = NULL;
	int res = 0;

	vlaue = (int *)malloc(sizeof(int)*(n+1));
	if(vlaue == NULL)
	{
		return -1;
	}

	memset(vlaue,0,sizeof(int)*(n + 1));
    vlaue[0] = 0;
	vlaue[1] = 1;
	vlaue[2] = 2;
	vlaue[3] = 3;
    res = helper(n,vlaue);
	free(vlaue);

	return res;
}

输出结果:
在这里插入图片描述

发布了71 篇原创文章 · 获赞 42 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chen1415886044/article/details/103865509
今日推荐