函数递归与重载(28)

函数的递归是在某个函数里(非主函数)自己调用自己,很显然必须在某条件下可以终止对自己的调用。

函数的重载是针对同名函数进行动态匹配,针对不同特点匹配特定函数实现。

递归

递归应该是算法设计的入门,现实生活中很多问题用递归的思想可以得到很好的解决。然而递归不是一种高效的算法。

函数的调用流程是这样的:主调函数发起函数调用-》主调函数暂停,保存现场-》进入被调函数-》被调函数执行完毕,恢复主调函数现场,主调函数继续执行。

递归调用需要不断地保存、恢复现场,效率并不高,但是很多问题都可以通过递归的思想来完成:

1、阶乘和斐波拉契:既可以递推,也可以递归;

     1! -> 2! -> 3!....    递推     

     n! -> n*(n-1)!  -> n*(n-1)*(n-2)! ..... ->n*(n-1)*(n-2).....1!     求n的阶乘转成求n-1,一直到已知的1的阶乘,然后再一层层返回。

   斐波拉契级数也一样。 

#include <iostream>
#include <stdio.h>
using namespace std;
int f1(int n) //递归求阶乘
{
	if(n==1 || n==0) return 1;
	return n*f1(n-1);
}
int f2(int n)  //递归求斐波拉契
{
	if(n==1 || n==2) return 1;
	return f2(n-1)+f2(n-2);
}
int main()
{
	cout<<f1(5)<<endl;
	cout<<f2(8)<<endl;
	return 0;
}

上面代码可以发现递归算法从代码方面而言非常的简练、求解的思想也非常清晰!

2、经典汉诺塔问题

A、B、C三个柱子,在A柱子从小到大叠有N个盘子,目标是把A柱子上的盘中移动到C柱子上,移动规则是不能用大盘中压住小盘中。

#include <iostream>
#include <stdio.h>
using namespace std;
void hanoi(int n,char A,char B,char C)//n个盘在A,要移动到C
{
	if(n==1) cout<<"第"<<n<<"号盘从 "<<A<<" 移动到 "<<C<<endl; //一个盘在A,直接移动到C
	else
	{
		hanoi(n-1,A,C,B);//多于一个盘,则把n-1个盘移动到B
		cout<<"第"<<n<<"号盘从 "<<A<<" 移动到 "<<C<<endl; //剩余的盘移动到C 
		hanoi(n-1,B,A,C); //再把B上的n-1个盘,移动到A
	}
}
int main()
{
	 hanoi(4,'A','B','C');
	return 0;
}

以上代码就非常让人惊讶了,如果用普通的逻辑推理,估计很难解决问题,这就是递归的优雅!

递归的特点:

1、递归是重复调用自己,每次调用肯定需要有些变化,其中变化的称为递归元;递归元可以是多个,称为多元递归;

2、递归可以直接自己调用自己,也可以间接调用,如A调用B,B又调用了A,称为间接递归;

3、递归需要有一个终止条件(不需要递归调用),并且递归元必须朝这个终止条件发展,否则将进入死循环

4、递归算法很优雅,但效率不高,递归算法的非递归化是算法研究的难点;

5、递归天然与”栈“这种数据结构相似,栈是一种线性结构(一维,有前后次序),满足后入先出的规则(类似穿衣服,最后穿的衣服先脱掉)。所以,很多时候可以用栈来描述递归算法(STL里)。

函数重载

函数是重名(相同函数名)调用时自动匹配函数定义,或者说同一个函数调用根据不同的条件调用不同的函数。规则:

重载的函数形参要么个数不同,要么类型不同(避免歧义)

void f1(int x)
{
}
void f1(int x,int y) //形参个数不同
{
}
void f1(float x,float y) //形参类型不同
{
}
void f1(int x,double y=10) //错误,与第一个定义冲突
{
}
int f1(int x)  //错误,函数类型(返回值)不能做为重载依据
{
	return 0;
}

调用时,通过实参找到最匹配(有可能都不匹配,但有一个最符合),如果有歧义也会报错:

  f1(1.5,6);   1.5是double  ,从第二、第三个都无法匹配,歧义       错误

  f1(5,6.1);  5是int   6.1是double  ,从第二比第三个更接近       调用第二个

  f1(5.0f,6.1);   5.0f是float   6.1是double  ,从第三比第二个更接近       调用第三个

  f1(5.0,6.0);   两个double , 二、三都不匹配,歧义,错误

  f1(5.0,6);     5.0是double ,  6是int  第二比较匹配,调用第二个

结论:在参数个数相同下,匹配规则就是计算相同的(不需要赋值转换的),如果两个函数相同个数一样就会歧义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值