栈及其应用PPT课件

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
栈及其应用
安庆四中
范江文
.
在现实生活中,常常会出现一些特殊的线性结构的情形。例如,我们在洗碗时, 总是将最后洗的碗叠在当前一列碗的最上面,而用的时候总是将最上面的碗,也 就是最后洗的碗先拿去用。类似的,储蓄罐、瓷坛等只有一个开口的容器存放物 品时,都是具有最后放的东西最先倒出来的特性。
图1是某个火车站的车厢调度储存室,进站的火车厢只能从左端进入,并从左端 出站。这个特殊的调度室也具有一端封闭的特性,因此最后调入的火车厢肯定最 先调出。我们将具有"先进后出"特性的特殊装置,称之为栈。
(2)如果S 只有一个数,那么S 为答案。否则,转到第一步继续操作。
上述算法,要扫描S 表达式n-1 次,每对S 做一次扫描,需要对S 的每个字符作 判断,如果S用链表存储,那么可以避免删除后的移动。因此时间复杂度为O(n2)。
一、栈的定义 从上面的例子,我们可以看出,栈(Stack)是一种特殊的线性表,它的特殊之
处在于限定仅能在表的一端进行插入或删除操作。换句话说,栈的操作是按后进 先出的顺序处理数据,因此栈又称后进先出表(Lastn First Out,LIFO)。
对于一个栈来说,我们习惯上称它的可操作端为栈顶 (Top),另一端为栈底 (Bottom)。设栈S=(a1,a2,···,an),a1端为栈底,an端为栈顶,则有: 1.插入一个元素an+1后,栈更新为S=(a1, a2,...,an,an+1) 2.从栈中删除一个元素后,栈更新为S=(a1,a2,,...,an-1)
top :integer; {栈顶指针} s: array [1.. Maxlength] of elemtype;{记录栈中元素的线性表) Procedure init;{初始化栈} function push (var st:stack;a:elemtype):boolean; {压栈,若栈不满,则在栈顶插入元素a,返回 true;否则返回false} function pop(stack):elemtype; {弹栈,若栈不为空则删除栈顶元素并返回元素值;否则返回NULL} procedure stack.init; Top<-0 {栈置空} function push(var st:stack;a:elemtype):boolean; If top<maxlength then begin inc(st.top);st.s[st.top]:=a; end else push:=fasle ; function pop():elemtype; If st.top=0 then 栈为空 else pop:=st.s[st.top]; dec(st.top);
.
三、栈的应用
(一)堆栈具有先进后出(后进先出)的特性,凡是具有这种特性的题目我们都可以用
堆栈来试一试。
[例1]编制一个满足下列要求的程序Baidu Nhomakorabea对于输人的任意一个非负十进制整数,打印输 出与其等值的八进制数。例如:(1348)10=(2504)8
这八进制的各个数位产生的顺序是从低位到高位的,而打印输出的顺序,一 般来说应从高位到低位,这恰好和计算过程相反。所以,堆栈的用武之地出来 了。具体做法就是把求到的数位先依次入栈,然后再依次出栈。
.
【例4】利用栈实现算术表达式求值 编写一个包含有“+”、“-”、“,”、“/”、“(”、“)”等运算符的表达式,计 算出该表达式的数值。
例如,3*(5-2)+7=3*3+7=9+7=16。
[分析] 对于给定的表达式计算,有一个运算符优先计算的问题,即“先算括号内,再算
括号外,先算乘除,再算加减,同一级别的算符从左到右进行运算”等。因此, 我们在计算过程中确定优先规则至关重要。对于任意一个表达式,我们可以将之 抽象成以下形式:
S=D1 op1 D2 op2 D3 op3 ..Di opi... Dn-1 opn-1 Dn,这里Di为操作数,opi 为运算符,i=l, 2,...,n-l,由此,我们得到如下算法:
(1)对S进行扫描,从opi中找一个最高优先级别的运算符进行操作 并将Di-1=Di-1 opi-1 Di。删除opi-1和Di.
.
特别的,不含任何元素的栈称为空栈。
二、栈的实现 1.栈的顺序存储结构
我们称用顺序结构存储的栈为顺序栈(array-based stack),即:利用连续的存储单元依次记录 栈的所有元素。一般来说,使用一维数组B存储栈的所有元素,变量top记录栈的大小,将s[1]叫作 为栈底,s[top]为栈顶。顺序栈Stack定义如下: TYPE Stack =record
.
[例3]给定N(N<=100000)个数,找出每个数后面第一个比它大的数的编号。没有输出0。 input: 3 2 6 1 1 2 output:3 3 0 6 6 0
先把题目要求的那个编号叫做后继编号。数列是按照从左往右的顺序编号的,在遇 到比它大的元素之前,是无法知道这个元素的后继编号的。并且是离后继编号元素最 近的元素先求出来,堆栈的用武之地又出现了。维护一个栈,栈里面存储所有尚未确 定后继编号的数,显然这个栈里的数是单调递减的。初始栈里没有数(或者有一个,就 是第一个数),然后对于每一个尚未处理的数,用它和栈顶的数比较,如果小于等于栈 顶,就入栈,如果大,就把栈顶的数出栈(这时候栈顶的数的后继编号),重复这一过程 直到这个数入栈或者栈为空(然后再入栈),接着继续处理剩下的数。
[例2]括弧匹配检验:假设表达式中允许包含两种括号即圆括号和方括号,其嵌套的 顺序随意,如([]())或[([][])]等为正确的匹配,[(])或([]()或()))均为错误的匹配。现在 的问题是,要求检验一个给定表达式中的括弧是否正确匹配?
看是否匹配,具体是看每个左括号是否有一个右括号跟它匹配。而且括号可 以嵌套,要检查外层括号是否匹配,必须先检查内层的括号是否匹配,也就是 先遇到的左括号后处理,这时,堆栈又有了用武之地。具体做法是遇到左括号 就入栈,遇到右括号就出栈并判断是否匹配。当括号串全部处理完毕,而且堆 栈为空,则是合法的,其他情况都是非法的。
相关文档
最新文档