zoukankan      html  css  js  c++  java
  • 栈的概念和应用

      栈是限定仅在表尾进行插入和删除操作的线性表。我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的找称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIF0结构。

    • 理解桟的定义需要注意:首先它是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的线性表而已。

      定义中说是在线性表的表尾进行插入和删除操作,这里表尾是指找顶,而不是栈底。它的特殊之处就在于限制了这个线性表的插入和删除位置,它始终只在栈顶进行。这也就使得:栈底是固定的,最先进栈的只能在栈底。栈的插入操作,叫作进栈,也称压栈、入栈。栈的删除操作,叫作出找,也有的叫作弹栈。

      

      应用一》中缀表达式转后缀表达式 

      我们把平时所用的标准四则运算表达式,即“9+(3-1)*3+10/2"叫做中缀表达式。因为所有的运算符号都在两数字的中间,现在我们的问题就是中缀到后缀的转化。

      中缀表达式“9+(3-1)*3+10/2”转化为后缀表达式“9 3 1-3*+ 10 2/+”

    • 规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。

      下面我们来具体看看这个过程。

      1. 初始化一空栈,用来对符号进出栈使用。

      2. 第一个字符是数字9,输出9,后面是符号“+”,进栈。

      3. 第三个字符是“(”,依然是符号,因其只是左括号,还未配对,故进栈。

      4. 第四个字符是数字3,输出,总表达式为9 3,接着是“-”进栈。

      5. 接下来是数字1,输出,总表达式为9 3 1,后面是符号“)”,此时,我们需要去匹配此前的“(”,所以栈顶依次出栈,并输出,直到“(”出栈为止。此时左括号上方只有“-”,因此输出“-”,总的输出表达式为9 3 1 -

      6. 接着是数字3,输出,总的表达式为9 3 1 - 3 。紧接着是符号“*”,因为此时的栈顶符号为“+”号,优先级低于“*”,因此不输出,进栈。

      7. 之后是符号“+”,此时当前栈顶元素比这个“+”的优先级高,因此栈中元素出栈并输出(没有比“+”号更低的优先级,所以全部出栈),总输出表达式为 9 3 1 - 3 * +.然后将当前这个符号“+”进栈。也就是说,前6张图的栈底的“+”是指中缀表达式中开头的9后面那个“+”,而下图中的栈底(也是栈顶)的“+”是指 “9+(3-1)*3+”中的最后一个“+”。

      8. 紧接着数字10,输出,总表达式变为9 3 1-3 * + 10。

      9. 最后一个数字2,输出,总的表达式为 9 3 1-3*+ 10 2

      10. 因已经到最后,所以将栈中符号全部出栈并输出。最终输出的后缀表达式结果为 9 3 1-3*+ 10 2/+

    • 从刚才的推导中你会发现,要想让计算机具有处理我们通常的标准(中缀)表达式的能力,最重要的就是两步:
    1. 将中缀表达式转化为后缀表达式(栈用来进出运算的符号)。
    2. 将后缀表达式进行运算得出结果(栈用来进出运算的数字)。

      整个过程,都充分利用了找的后进先出特性来处理,理解好它其实也就理解好了栈这个数据结构。

      应用二.平衡符号

      问题描述: 在编写代码并且编译时,难免会因为少写了一个')'和被编译器报错。也就是说,编译器会去匹配 括号是否匹配。当你输入了一个'(',很自然编译器回去检查你是否有另一个')'符号与之匹配。如果所有的括号都能够成对出现,那么编译器是能够通过的。否则编译器会报错。例如字符序列“(a+b)”是匹配的, 而字符序列"(a+b]"则不是。

      栈的应用:检查每件事情是否能成对出现,算法叙述:做一个空栈。读入字符直到文件结尾。

    1. 如果字符是一个开放符号,则将其推入栈中。

    2. 如果字符是一个封闭符号,则当栈为空时报错。否则,将栈元素弹出。如果弹出的符号不是对应的开放符号,则报错

    3. 在文件结尾,如果栈非空则报错。

      应用三.后缀表达式计算

      为了解释后缀表达式的好处,我们先来看看,计算机如何应用后缀表达式计算出最终的结果20的。后缀表达式:9 3 1-3*+ 10 2/+

    • 规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。

      下面是详细的步骤:

      1. 初始化一个空栈。此桟用来对要运算的数字进出使用。

      2. 后缀表达式中前三个都是数字,所以9、3、1进栈。

      3. 接下来是减号“-”,所以将栈中的1出栈作为减数,3出栈作为被减数,并运算3-1得到2,再将2进栈。

      4. 接着是数字3进栈。

      5. 后面是乘法“*”,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈。

      6. 下面是加法“+”,所以找中6和9出找,9与6相加,得到15,将15进栈。

      7. 接着是10与2两数字进栈。

      8. 接下来是符号因此,栈顶的2与10出栈,10与2相除,得到5,将5进栈。

      9. 最后一个是符号“+”,所以15与5出找并相加,得到20,将20进栈。

      10. 结果是20出栈,栈变为空。

    • 果然,后缀表达法可以很顺利解决计算的问题。但是我有个疑问,就是这个后缀表达式“9 3 1-3*+ 10 2/+”是如何通过算式“9+(3-1)*3+10/2”变化而来呢?

      后缀转中缀。

  • 相关阅读:
    ubuntu下文件安装与卸载
    webkit中的JavaScriptCore部分
    ubuntu 显示文件夹中的隐藏文件
    C语言中的fscanf函数
    test
    Use SandCastle to generate help document automatically.
    XElement Getting OuterXML and InnerXML
    XUACompatible meta 用法
    Adobe Dreamweaver CS5.5 中文版 下载 注册码
    The Difference Between jQuery’s .bind(), .live(), and .delegate()
  • 原文地址:https://www.cnblogs.com/wxgblogs/p/5467274.html
Copyright © 2011-2022 走看看