3.2.1栈的应用(1)

一、递归函数的非递归实现

递归函数本身就是用栈来实现的,只是我们看不见而已。

1.当一个函数在调用另一个函数时,要做三件事情:

a)保存实参,返回地址等信息(保护现场);

b)为被调用函数的局部变量分配存储区;

c)将控制转移到被调用函数的入口。

2.从被调用函数返回调用函数之前,也要做三件事情:

a)保存被调用函数的计算结果,并恢复现场

b)释放被调函数的数据区;

c)将控制转回到调用函数。

*其中函数调用自己就是递归的过程。

我们可以知道:函数调用是通过栈实现的,而递归的本质是函数调用->递归可以用栈消除。

3.函数执行过程

流程分析:如图,在main函数中运行到r:f1()时,此时有三个过程,r此时是一个断点,我们将r入栈,然后将前面所有程序走过的有参数的值保留起来,再将控制权转给f1函数;之后的f1函数也是如此,在f2函数走完之后,我们再将栈中的t出栈在f1继续完成f1函数,之后r再出栈,完成主函数的流程。

再如快速排序的函数quicksort:

那么,我们如何用非递归的形式实现递归呢?答案肯定是栈。

流程:

我们先确定目标为第一个元素,如图为6,此时数组排序为0-5;

之后我们将6与右边(也就是其他所有元素)作比较,算出比它小的和比它大的元素各有多少,如图,左边下标是0-2,右边是4-5;

然后该数组有了两个区域,我们再对两个区域分别进行刚才相同的步骤,如此循环,可以看见,该步骤和递归的方式原理其实是一样的

二、符号的平衡检测

在这方面我们主要解决如何使用栈解决符号的配对问题,即判断栈顶的括号是否和栈底的符号相配对。

1.算法部分(CheckBalance()函数)

①首先创建一个空栈;

②从源程序中读入符号;(读入符号不像是读入字符,有些符号由多个字符组成,读入符号的过程更多

③如果读入的符号是开符号,那就将其进栈;

④如果读入的符号是一个闭符号,但栈是空的,则出错,否则,将栈中的符号出栈;

⑤如果出栈的符号和读入的闭符号不匹配,出错;

⑥继续从文件中读入下一个符号,非空则转向③,否则转向⑦;

⑦如果栈非空,报告出错,否则括号配对成功。

备注:其中②可以使用GetNextSymbol函数,第⑥步可以使用CheckMatch()函数。

2.读取符号(GetNextSymbol())的步骤

①读取一个字符ch1;(Nextchar())

②如果ch1='/',则再读取一个ch2;

如果ch2='*',则跳过紧着着的Comment;(SkipComment())

如果ch2='/',则跳过本行的Comment;

否则,回退ch2;(PutBackChar())

③如果ch1!='/',则判断:

如果ch1='\'或者'''',则跳过字符常量或字符串变量;

如果ch1='{'或‘}’等,则返回字符ch1。

符号的平衡性检测实际上就是检测开闭符号(比如说括号)的平衡性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值