Chapter 3 栈与队列

文章目录

  • 1. 栈
    • 1.1 栈的定义
    • 1.2 栈的顺序和链式存储
    • 1.3 共享栈
  • 2. 队列
    • 2.1 队列的定义
    • 2.2 循环队列
    • 2.3 链式队列
    • 2.4 双端队列
  • 3. 栈与队列的应用
    • 3.1 栈在括号匹配中的应用
    • 3.2 栈在表达式求值中的应用 P95
    • 3.3 栈在递归中的应用
    • 3.4 队列在层次遍历中的应用
    • 3.5 队列在计算机系统中的应用

1. 栈

1.1 栈的定义

通常,栈可定义为只允许在表的末端进行插入和删除的线性表。后进先出(LIFO)

栈的基本操作

  • InitStack(&S):初始化一个空栈
  • StackEmpty(S):判断一个栈是否为空
  • Push(&S, x):进栈
  • Pop(&S, &x):出栈
  • GetTop(S, &x):读栈顶元素
  • DestroyStack(&S):销毁栈

解答算法题时,若题干未做出限制,则可直接使用这些基本的操作函数。

1.2 栈的顺序和链式存储

P60-P62

1.3 共享栈

利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数据空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。

共享栈是为了更有效地利用存储空间,两个栈的空间互相调节,只有在整个存储空间被占满时才发生上溢。其存取数据的时间复杂度均为 O ( 1 ) O(1) O(1),所以对存取效率没有什么影响。

2. 队列

2.1 队列的定义

队列是另一种限定存取位置的线性表,它只允许在表的一端插入,在另一端删除,允许插入的一端叫做队尾(rear),允许删除的一端叫做队头(front)。先进先出(FIFO)。

队列常见基本操作

InitQueue(&Q); //初始化队列
QueueEmpty(Q); //判断队列是否为空
EnQueue(&Q, x); //入队
DeQueue(&Q, &x); //出队
GetHead(Q, &x); //读队头元素

2.2 循环队列

循环队列操作

  • 初始时:front==rear=0;
  • 队头指针进1:front=(front+1)%MaxSize;
  • 队尾指针进1:rear=(rear+1)%MaxSize;
  • 队列长度:(rear+MaxSize-front)%MaxSize;

判断队空队满
用(rear+1)%MaxSize==front 来判断是否队已满,即让rear指到front前一个位置就认为队已满。所以在队满情形实际空了一个元素位置。如果不留这个空位,导致 r e a r = = f r o n t rear==front rear==front就会混淆队空队满条件。所以,在循环队列中,最多只能存放MaxSize-1个元素

2.3 链式队列

队列的队头指针指向单链表的第一个结点,队尾指针指向单链表的最后一个结点。
用单链表表示的链式队列特别适合于数据元素变动比较大的情形,而且不存在队列产生溢出的情况。

2.4 双端队列

双端队列可以在队列的两端进行插入和删除。有的可能有限制,比如限制输入(一端输入,两端输出)或限制输出(一端输出,两端输入)

3. 栈与队列的应用


3.1 栈在括号匹配中的应用

算法思想如下:

  1. 初始设置一个空栈,顺序读入括号。
  2. 若是右括号,则或者使置于栈顶的最急迫期待得以消解,或者是不合法情况(括号序列不匹配,退出程序)。
  3. 若是左括号,则作为一个新的更急迫的期待压入栈中,自然使原有的在栈中的所有未消解的期待的急迫性降了一级。算法结束时,栈为空,否则括号序列不匹配。

3.2 栈在表达式求值中的应用 P95

任何一个表达式都是由操作数(亦称运算对象)、操作符(亦称运算符)和分界符组成。通常,算术表达式有三种表示:

  • 中缀(infix)表示:<操作数><操作符><操作数> 例如:A+B
  • 前缀(prefix)表示:<操作符><操作数><操作数> 例如:+AB
  • 后缀(postfix)表示:<操作数><操作数><操作符> 例如:AB+

由于中缀表示有操作符的优先级问题,还有可加括号改变运算顺序的问题,所以对于编译程序来说,一般不使用中缀表示处理表达式,因为用后缀表示计算表达式的值只用一个栈,而前缀中缀两个栈,所以编译程序一般使用后缀表示求解表达式的值

利用栈将中缀转换成后缀

  • isp叫栈内优先数
  • icp叫栈外优先数

算法见P99

该转换算法对输入表达式只进行一次自左向右的扫描,对每个操作数只执行一次输出,其执行时间为 O ( 1 ) O(1) O(1),对每个操作符,执行进栈和退栈各一次,其时间也为 O ( 1 ) O(1) O(1)。若表达式中符号的总数为n,则总的执行时间复杂度为 O ( n ) O(n) O(n)

3.3 栈在递归中的应用

3.4 队列在层次遍历中的应用

3.5 队列在计算机系统中的应用

你可能感兴趣的:(DataStructure,栈,队列)