栈和队列是两种重要的线性结构。从数据结构角度看,栈和队列也是线性表,其特殊性在于栈和队列的基本操作是线性表操作的子集,它们是操作受限的线性表。但从数据类型角度看,它们是和线性表大不相同的两类重要的抽象数据类型。

栈的定义

栈(Stack)是限定只能在表的一端进行插入和删除操作的线性表。
允许插入和删除运算的一端称作栈顶(top)
不允许插入和删除的另一端称作栈底(bottom)
在栈顶进行的插入操作称为入栈或进栈(push)
在栈顶进行的删除操作称为出栈或退栈(pop)
栈的特点:后进先出
LIFO(Last In First Out)
数据结构与算法-栈

栈的抽象数据类型

ADT Stack
数据元素集合
具有相同性质数据元素的一个有限序列,且只
能在称为栈顶的一端进行插入和删除操作。
基本操作
创建栈(Stack):创建空栈
入栈(push):在栈顶插入新的数据元素
出栈(pop):删除栈顶数据元素
取栈顶元素(peek):获取栈顶的数据元素
判栈空(isEmpty):判断栈是否为空栈

如何用数组表示栈?

存储栈元素
栈的逻辑结构表示
指示栈的栈顶

顺序栈的最大容量是element.length;
top为栈顶元素的下标,0 <= top <= element.length-1
栈空:this.top = -1;
栈满:this.top = element.length-1
数据结构与算法-栈
数据结构与算法-栈
进栈、出栈、取栈顶等算法时间复杂度都是O(1)。
进栈和出栈相当于在顺序表中进行插入和删除,只是此时操作对象是线性表最后一个元素,无须移动大量元素。从本质上来讲,栈的操作是对线性表操作的“简化”,顺序表允许的操作在栈里可能会不允许进行。

栈的应用

实现嵌套调用或递归调用
实现非线性结构的深度遍历算法
以非递归方式实现递归算法

栈是嵌套调用机制的实现基础
数据结构与算法-栈

栈的应用之数制转换
数制转换原理:
 十进制数N和其他d进制数的转换基于下列原理:
N = (N div d)×d + N mod d (div 为整除,mod 为求余)
重复以下两步,直到N 等于0。
X = N mod d // mod 为求余运算
N = N div d // div 为整除运算
最后得到的一系列余数就是转换后的结果。
数据结构与算法-栈

操作步骤(除留余数法):
① 将N除以d,取其商和余数;
② 判断商是否为零;
若商不为零,则将商赋值给N,并转向① ;
若商为零,则转换结束。
最先求得的余数是N进制数的最低位,最后求得的余数是N进制数的最高位,即运算顺序与求得的八进制数的各位数字的次序相反,符合栈的特点。

栈的应用之表达式求值
算术表达式的定义
任何一个表达式都是由操作数、运算符和界限符组成。
算术表达式三种形式
前缀表达式=运算符+操作数1+操作数2
中缀表达式=操作数1+运算符+操作数2
后缀表达式=操作数1+操作数2+运算符

中缀表达式的运算规则

先计算括弧内后计算括弧外;
在无括号或同层括号内时,先乘除后加减、
同一优先级运算,先左后右
示例:
16-4×(2+1)
结果:4
(110+16)/(16-9×(4+3))
结果:-2

后缀表达式的特点与运算规则

没有括号,也无需考虑优先级,运算符在式中出现的顺序恰为表达式的运算顺序;
对比:
中缀表达式:
a - b * ( c / d ) + e
后缀表达式:
a b c d / * - e +

相关文章: