数据结构--2.3 栈与递归

累加

累加可以用for循环,也可以用递归。代码如下:

#include <stdio.h>
#include <malloc.h>

int addTo(int n)
{
	if(n<=0)
	{
		return 0;
	}else
	{
		int num;
		num=addTo(n-1)+n;
		return num;
	}
}

int main()
{
	int num;
	num=addTo(5);
	printf("%d",num);
}

这个递归算法的时间复杂度是O(n),而for的时间复杂度却只有O(1),那我们为什么还要选择递归呢?因为递归有利于我们理解更复杂的问题,比如下面展示的经典的汉诺塔问题。

汉诺塔问题

算法说明

汉诺塔问题已经在不同课堂上反复听过很多遍了,这是一个十分经典的题:有A,B,C三根柱子,我们需要把A柱子上的n个圆盘挪到C柱子上。在挪动时有两个要求:
1.每次只能挪动一个盘子;2.小盘子只能放在大盘子上。
我们需要求挪动n个盘子,要挪动多少次。

那根据递归的思想,求挪动n个盘子的次数,我们只需要知道挪动(n-1)个盘子的次数,挪动(n-1)个盘子的次数,我们又只需要知道挪动(n-2)个盘子的次数,这样就可以形成一个递归的表达式。

我列出了三个盘子的挪动方式,如下图:
在这里插入图片描述
在这里插入图片描述

代码实现

int hanoi(int n,char Source,char Target,char Assist)//Source代表圆盘柱,Assist代表辅助柱,Target代表目标柱
{
	if(n<=0)
	{
		return 0;
	}else
	{
		hanoi(n-1,Source,Assist,Target);
		printf("%c -> %c\r\n",Source,Target);
		hanoi(n-1,Assist,Target,Source);
	}
} 

从这段代码我们可以看出来只需要三步将A柱子上n-1个盘子借助C柱子移到B上,将A最后一个盘子移到C上,最后将B柱子借助空A柱子移到C上。:

A -> B
A -> C
B -> C
A -> B
C -> A
C -> B
A -> B

时间复杂度与空间复杂度

汉诺塔问题的时间复杂度是O(2^n),
设盘子个数为n时,需要T(n)步,把A柱子n-1个盘子移到B柱子,需要T(n-1)步,A柱子最后一个盘子移到C柱子一步,B柱子上n-1个盘子移到C柱子上T(n-1)步,得递推公式T(n)=2T(n-1)+1,所以汉诺塔问题的时间复杂度为O(2^n)。
空间复杂度是O(n)。

总结

递归的思想在解决简单的问题是会显得多此一举,但是在解决复杂问题时却可以将问题变得十分简洁,可以看出这是一种比较高级的算法思想。
递归算法有两个必要条件:
1.必须存在终止条件(即递归出口);
2.过程的描述包含它本身,就是在过程或函数中调用自身。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值