zoukankan      html  css  js  c++  java
  • (转)(c#)数据结构与算法分析 栈与队列

     

    栈stack    
        栈是一种先进后出机制,它只允许访问访问一个数据项,即 栈顶(最后插入的数据项)。它有主要的三种操作:push,向栈内压入值;pop,弹出栈顶的值,即返回栈顶的值,并把它从栈内删除;peek,只返回但不删除栈顶。
        
        概念很容易理解,无非就像给弹匣压子弹等等这种类比,但是像我这样的新手在刚接触到栈的时候总是很迷茫,认为它很难,其实这只是错觉,主要是因为没有搞清楚栈主要用在那些场景。

        栈普遍应用于编译器、文本检测、科学计算等等,在编译器中,它用来检测一个函数体等是否为封闭的(括号是否成对等等),在文本检测中,想想你的vs,如果最后没有大括号它就会检测出来,和编译器中一样,在科学计算中,就像商店能买到的那些高级计算器,输入一个算式可以直接计算出来结果,而不像普通计算器中,只能输入数字,然后在按键一步一步计算,以上这些应用场景,归根结底都是对文本的检测,现在知道栈的用途了吧,后面将结合队列一起练练手。

    队列queue
        顾名思义,就是一堆东西成队排列了,它是先进先出机制(FIFO)与栈相反,栈是后进后出(LIFO)。它的主要操作有:Enqueue,向队尾添加值;Dequeue,返回并移除对头的值;peek,返回但不移除对头的值。

        队列很容易理解,它主要应用在网络通信、系统等。windows的所有事件都是放在队列里面的。

        最典型的,就是系统的任务分配了,每个进程或线程都分配在某些队列里,方便cpu时间片的分配调度,任务的运行不可能是你最后打开的程序先运行吧,当然它有优先级,这个排除在外。

    栈的应用
        现在搞清楚了栈和队列的应用场景,那就趁热打铁,练练手。

        现在,按部就班的实现一个科学表达式的计算。

        首先了解一下计算机是怎么计算类似于 1*(2+3)+4/2 这样的计算。对于大脑来说,这个算式简单到不能再简单了,但是电脑却不是如此,得让它明白那个先算,那个后算,以及哪些是操作符(运算符)哪些不是(例如括号)。

        像我们经常使用的这种算式称为 中缀式 ,就是运算符都在两个操作符中间了,这种中缀式对于我们人脑来说,并不是顺序执行的,它可以从中间先开始,比如1+2*3 ,这正是电脑很难理解中缀式的原因,因为他总是顺序执行的。那么,我们就得把中缀式换成 后缀式(postfix)  或称作 逆波兰记法(reverse Polish notation)。

        中缀式就是把运算符放到两个操作数后边,让算式保持顺序计算(对于我们人脑也是如此)。具体怎么放,大家看看下面的例子就明白了。
         
        
    示例 1:

    中缀式

    后缀式

    A+B+C-D A B+C+D-
    A*B/C+D A B*C/D+
    A*(B+C*D)+E A B C D * + * E +
    (A+B)*C/(D+E-F) A B + C * D E + F - /
    A+B*C+(D*E+F)*G A B C * + D E * F + G * +

        结合上边的示例,会发现后缀式并没有描述优先级的括号,这是因为括号并不是运算符。大家在自己动手做两个,就掌握这种方法了。
        
        程序中如何实现这种转换呢?那就要依靠强大的栈了。

    中追到后缀的转换 
       
  • 当读到一个操作数时,立即把它放到输出中,即显示出来。操作符不立即输出,从而必须先存在某个地方,例如栈或变量。当遇到一个左括号时也把它放入栈中。计算是从一个初始化为空的栈开始。
  • 如果栈为空,则将符号入栈。
  • 如果遇见一个右括号,那么就将栈元素弹出并输出,直到遇到一个(相对应的)左括号,但是这个左括号只弹出,并不输出。
  • 如果遇见优先级与栈首元素相同或比较低的符号,则将栈的所有元素弹出并输出,直到遇见一个左括号为止,这个左括号只弹出,并不输出,最后,将遇到的那个符号入栈。
  • 如果遇见优先级与栈首元素高的符号(右括号除外),则把它入栈。
  • 如果遇见右括号,则弹出并输出所有元素,直到遇到一个与之相对应的左括号,这个左括号只弹出不输出。
  • 如果读到末尾了,则将栈中元素弹出并输出,直到栈为空,左括号只弹出不显示


     

版权说明:作者:张颖希PocketZ's Blog
出处:http://www.cnblogs.com/PocketZ
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
若本文为翻译内容,目的为练习英文水平,如有雷同,纯属意外!有不妥之处,欢迎拍砖

查看全文
  • 相关阅读:
    char和QChar(Unicode的编码与内存里的值还不是一回事)
    ddd
    vim实用笔记
    设计思想
    await使用中的阻塞和并发
    单元测试
    C#简单实现贪吃蛇程序(LinQ + Entity)
    JS逗号、冒号与括号
    C#实现对文件目录的实时监控
    在线预览PDF
  • 原文地址:https://www.cnblogs.com/PocketZ/p/1711982.html
  • Copyright © 2011-2022 走看看