Dotcpp  >  编程教程  >  算法基础  >  递归算法概念与实例讲解

递归算法概念与实例讲解

点击打开在线编译器,边学边练

本篇主要是围绕着递归算法的概念、实质、思想以及设计要素四个方向叙述,同时通过实例讲解,促进大家对递归算法的理解。


一、算法概念

递归算法是一种直接或者间接调用自身函数或者方法的算法。说简单了就是程序自身的调用。


二、算法实质

递归算法就是将原问题不断分解为规模缩小的子问题,然后递归调用方法来表示

问题的解。(用同一个方法去解决规模不同的问题)


三、算法思想

递归算法,顾名思义就是有两个大的阶段:递和归,即就是有去(递去)有回(归来)。

递去:将递归问题分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决

归来:当你将问题不断缩小规模递去的时候,必须有一个明确的结束递去的临界点(递归出口),一旦达到这个临界点即就从该点原路返回到原点,最终问题得到解决。

递归的图解分析

递归的图解分析


四、递归算法的设计要素

递归思维是一种从下向上的思维方式,使用递归算法往往可以简化我们的代码,而且还帮我们解决了很复杂的问题。递归算法的难点就在于它的逻辑性,一般设计递归算法需要考虑以下几点:

(1)明确递归的终止条件

(2)提取重复的逻辑,缩小问题的规模不断递去

(3)给出递归终止时的处理办法


五、递归算法的经典实例

(1)阶乘

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

//阶乘
int recursive(int i)
{
	int sum = 0;
	if (0 == i)
		return (1);
	else
		sum = i * recursive(i-1);
	return sum;
}

(2)河内塔问题

河内塔问题

(3)全排列

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

如1,2,3三个元素的全排列为:

  1,2,3

  1,3,2

  2,1,3

  2,3,1

  3,1,2

  3,2,1

//全排列
inline void Swap(int &a,int &b)
{
	int temp=a;
	a=b;
	b=temp;
}
void Perm(int list[],int k,int m)
{
	if (k == m-1) 
	{
		for(int i=0;i<m;i++)
		{
			printf("%d",list[i]);
		}
		printf("n");
	}
	else
	{
		for(int i=k;i<m;i++)
		{
			Swap(list[k],list[i]); 
			Perm(list,k+1,m);
			Swap(list[k],list[i]); 
		}
	}
}


(4)斐波那契数列

斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……

这个数列从第三项开始,每一项都等于前两项之和。

有趣的兔子问题:

斐波那契数列

一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?

分析如下:

第一个月小兔子没有繁殖能力,所以还是一对;

两个月后,生下一对小兔子,总数共有两对;

三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,总数共是三对;

……

依次类推可以列出下表:

经过月数012345678
9101112
幼崽对数
101123581321345589
成兔对数01123581321345589144
总体对数1123581321345589144233
//斐波那契
long Fib(int n)
{
	if (n == 0) 
		return 0;
	if (n == 1) 
		return 1;
	if (n > 1) 
		return Fib(n-1) + Fib(n-2);
}



知识点标签:递归


本文固定URL:https://www.dotcpp.com/course/925

算法竞赛教程
第一章 算法基础
第二章 搜索算法
第三章 排序算法
第四章 字符串相关
第五章 数学相关
第六章 动态规划
第七章 数据结构
第八章 图论
第九章 计算几何
第十章 其他算法
Dotcpp在线编译      (登录可减少运行等待时间)