栈与递归函数

​前言

本文主要介绍栈的基本原理,建立在栈的基础上对递归的原理加以阐述。


一、栈的原理

我们都曾经在高中阶段学习过进制转化算法和秦九韶算法,表面上看,因为二者都是处理多项式(把10进制数n转化为p进制数实际上等价于n=\sum_{0}^{n} c_{i}\cdot p^{i})但深层次看来,实际上二者都使用了递归,或者说栈的思路。

那么栈是什么呢?泛泛而谈,是只能在一端进行插入删除操作的逻辑结构。比方说,对一个数组,我们只有一个指针(head)描述数组的实际大小,新输入(入栈)数组的数要先跟指针申请,让他上移一位,“腾出”一个空间。移除(出栈)一个数也要告知指针,让他向下移动一位,以声明“这个出栈的数已经不复存在”。有的时候指针腾不出空间,就会报错“上溢”(overflow),有的时候指针指到了a[0]之下的空间,也会报错“下溢”(underflow)。

我们可以看见:对于一个栈,操作head并不能影响栈所能达到的最大容量(n)。

                         head下移,并没有真的删除刚才的元素,只有再次入栈才会替换他。

                         栈基于数组可以存储,但实际上也可以只利用head指针,而不关心存储了什么。

他无疑就是一个逻辑结构。不是说数组真的只能单向操作,而是我们用栈思维将他串联起来。

标准的出入栈函数定义如下:这并不难理解


​虽然按照定义上溢是>=n,下溢是<=0,但是没有人会定义一个长度为0的栈,且出入栈只能逐个增减head的“值”,所以条件只要判断head==n,即满栈为真,就不允许元素再入栈。只要条件判断head==0为真,即空栈为真,就不可以再出栈。


二、栈的实例 

 我们用最经典的火车调度为例:

图片来自《信息学奥赛一本通》:

一眼就能看出来,车站就是一个“栈”;

如果12345入,假设35241出

火车不能穿透前方的车,正常行驶,1号车会始终在最前方。

想要3号车最先出来,必须想办法让3出现在最前面,这通过栈来实现。

因为“后进栈先出栈”,进栈后123(A视角)就变成了321(B视角)。

3号车在1,2号车后面,只有1,2号车都进入栈内,3号车才能成为第一个出栈的元素 。

接下来只有4先进栈,5才能先进栈再出栈,成为第二个出栈的元素。

接下来4必须在2之前出去,但是假设要求2先出栈,故不可能,这个假设就是不可能的。


三、递归的原理与实例

一般定义递归为自身调用自身的函数,但我们还要想清楚为什么要自己调用自己。

递归就是通过栈来构建的,比如说秦九韶算法,人的思路是这样进行的;

图片来自百度百科:

 实际上,以求解一个n次多项式的值为例,假设值为f(n)

f(n)=f(n—1)*x+c(n);

然后f(n-1)不知道,再把它写成

f(n-1)=f(n-2)*x+c(n-1);

以此类推,

直到f(1)=f(0)*x+c(1);

f(0)=c;终止递归。

我们不断调用自身,实质上是把f(n),f(n-1)……f(0)的表达式和变量由先到后压进栈内,然后凭借递归终止条件,把最后入栈的f(0)出栈,之后依次把高次的表达式出栈,直到返回f(n)的值。

我们之所以对递归感到怀疑,是因为不清楚其中的涉及栈的历程。

先对秦九韶算法代码实现如下:

例子,计算4*x^4+3*x^3+2*x^2+1*x+1,x=5

秦九韶算法的计算顺序与人阅读多项式的顺序一致,最内层括号内是最高次项的系数,这一过程可以很容易手写。计算机算法对于系数的输入顺序也是从高次到低次,从“左”到“右”。

运行结果:答案为2931

 

 


the end

参考资料:百度百科词条——秦九韶算法(代码为本文作者原创)

                  信息学奥赛一本通——栈

活动地址:CSDN21天学习挑战赛

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值