栈及其应用

栈 Stack

  栈又称堆栈,是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算。

  把对栈进行运算的一端称为栈顶,另一端称为栈底。

  向一个栈插入新元素称为入栈或进栈,Push;从一个栈删除元素称为退栈或出栈,Pop。

  因为后进栈的元素必定先出栈,所以又把栈称为后进先出表(Last In First Out, LIFO)。

 

栈的顺序存储结构

  栈的顺序存储结构需要使用一个数组和一个整型变量来实现。利用数组来顺序存储栈中的所有元素,利用整型变量来存储栈顶元素的下标位置,可这个变量称为栈顶指针。

  可以定义如下:

const int MaxSize = 50;
struct Stack
{
    ElemType stack[MaxSize];
    int top;
};

 

  若要对存储栈的数组空间采用动态分配,则可定义如下:

struct Stack
{
    ElemType *stack;
    int top;
    int MaxSize;
};

  top的值为-1表示栈空。

 

栈的链式存储结构

  栈的链式存储结构是通过由结点构成的单链表实现的,此时表头指针被称为栈顶指针,由栈顶指针指向的表头结点被称为栈顶结点,整个单链表被称为链栈。

  对链栈的插入和删除操作是在单链表的表头进行的。

  当向一个链栈插入元素时,是把该元素插入到栈顶,即,使该元素结点的指针域指向原来的栈顶结点,而栈顶指针则修改为指向该元素结点,使该结点成为新的栈顶结点。

 

栈的应用

简单应用

  1.输入,之后逆序输出。

  2.语法检查:括号匹配。

  每当扫描到大中小的左括号后,令其进栈,当扫描到右括号时,则检查栈顶是否为相应的左括号,若是则退栈处理,若不是则出现了语法错误。当扫描到文件结尾,若栈为空则表明没有发现括号配对错误。

  3.数制转换:把十进制的整数转换为二至九之间的任一进制数输出。

  转换方法:要转换为r进制,则原来的数逐次除以基数r(除完之后用商再除),直到商为0,得到的一系列余数的逆序就是转换结果。

算术表达式的计算

  在中缀表达式(就是我们人类通常写的算术表达式)中,计算需要注意优先级、括号这些问题,和运算符的实际运算次序往往同它们在表达式中的先后次序不一致,所以波兰科学家提出了后缀表达式,把运算符放在两个运算对象的后面。

  在后缀表达式中看,不存在括号,也不存在运算符优先级的差别,计算过程完全按照运算符出现的先后次序进行,整个计算过程仅需扫描一遍便可完成。

中缀表达式转换成后缀表达式:

  中缀算术表达式转换成对应的后缀算术表达式的规则是:把每个运算符都移到它的两个运算对象的后面,然后删除掉所有的括号即可。

  为了转换正确,必须设定一个运算符栈,并在栈底放入一个特殊算符,假定为@,让它具有最低的运算符优先级,此栈用来保存扫描中缀表达式得到的暂不能放入后缀表达式中的运算符,待它的两个运算对象都放入到后缀表达式之后,再令其出栈并写入到后缀表达式中。

  转换过程如下:从头到尾扫描中缀表达式,若遇到数字则直接写入后缀表达式,若遇到运算符,则比较栈顶元素和该运算符的优先级,当该运算符的优先级大于栈顶元素的时候,表明该运算符的后一个运算对象还没有进入后缀表达式,应该把该运算符暂存于运算符栈中,然后把它的后一个运算对象写入到后缀表达式中,再令其出栈并写入后缀表达式中;若遇到的运算符优先级小于等于栈顶元素的优先级,表明栈顶运算符的两个运算对象已经被写入后缀表达式,应将栈顶元素出栈并写入后缀表达式,对于新的栈顶元素仍进行比较和处理,直到栈顶元素的优先级小于当前等待处理的运算符的优先级为止,然后令该运算符进栈即可。

  按照上述过程扫描到中缀表达式的末尾,把剩余的运算符依次出栈并写入后缀表达式即可。

  (对于左括号直接进栈,右括号则使左右两个括号内的运算符都出栈)。

后缀表达式求值

  后缀表达式求值也需要一个栈,其元素类型为操作数的类型,此栈存储后缀表达式中的操作数、计算过程的中间结果及最后结果。

  计算过程如下:扫描后缀表达式,若遇到操作数则进栈,若遇到操作符则弹出两个操作数进行计算,然后将结果压进栈,直到最后扫描完毕,栈中应该保存着最终结果。

栈与递归

  在计算机系统内,执行递归函数是通过自动使用栈来实现的,栈中的每个元素包含有递归函数的参数域、每个局部变量域和调用后的返回地址域,其中引用参数域只保存传送来的实参的地址。每次进行函数调用,都把相应的值压入栈,每次调用结束,都按照本次返回地址返回到指定位置执行,并且自动做一次退栈操作。

  关于递归的应用就又是一个大话题了,此处就不多说了。

posted @ 2012-11-07 21:40  圣骑士wind  阅读(5800)  评论(0编辑  收藏  举报