3.1.2 栈和队列

2025-06-15 22:23:04 更新

栈和队列是常用的两种数据结构,逻辑结构与线性表相同。

特点:栈“后进先出”,队列“先进先出''。

(一)栈的定义

栈:称为先进后出(FILO)或后进先出(LIFO)线性表。是只能通过访问一端来实现数据存储和检索的线性数据结构。

修改原则:“先进后出”。

栈顶(top):在栈中进行插入和删除操作的一端

栈底(bottom):另一端。

空栈:不含数据元素的栈。

(二)栈的基本运算

①初始化栈initStack(S):创建一个空栈S。

②判栈空isEmpty(S):当栈S为空栈时,返回“真”值,否则返回“假”值。

③入栈push(S,x):将元素x加入栈顶,并更新栈顶指针。

④出栈pop(S):将栈顶元素从栈中删除,并更新栈顶指针。若需得到栈顶元素值,可将pop(S)定义为一个函数,它返回栈顶元素的值.

⑤读栈顶元素top(S):返回栈顶元素的值,但不修改栈顶指针。

(三)栈的存储结构


存储结构

说明

1

栈的顺序存储

用一组地址连续的存储单元依次存储自栈顶到栈底的数据元素,同时附设指针top指示栈顶元素位置。

顺序栈:采用顺序存储结构的栈。

顺序存储时,栈空间容量有限,需要预先定义或申请栈的存储空间。

当一个元素入栈时,需要判断是否栈满(栈空间中没有空闲单元),若栈满,则元素入栈会发生上溢现象。

2

栈的链式存储

顺序存储的栈可能存在上溢,所以用链表存储栈中的元素。

链栈:用链表作为存储结构的栈。

栈中元素的插入和删除仅在栈顶一端进行,不必设置头结点,链表头指针就是栈顶指针。

(四)栈的应用

(1)典型应用

  1. 表达式求值
  2. 括号匹配

(2)将表达式转换为后缀形式

计算后缀表达式时,从左至右扫描后缀表达式:若遇到运算对象,则压入栈中;遇到运算符,则从栈中弹出相应运算对象进行计算,并将运算结果压入栈中。重复以上过程,直到后缀表达式结束。

举例:表达式46+5*(120-37)的后缀表达式形式为46 5 120 37-*+

计算过程:

①依次将46、5、120、37压入栈中。

②遇到-,弹出37、120,计算120-37,得83,将其压入栈中。

③遇到*,弹出83、5,计算5*83,得415,将其压入栈中。

④遇到+,弹出415、46,计算46+415,得461,将其压入栈中。

⑤表达式结束,则计算过程完成。

(五)队列定义

队列:是一种先进先出(FIFO)的线性表,只允许在表的一端插入元素,而另一端删除元素。

队尾(rear):允许插入元素的一端。

队头(front):允许删除元素的一端。

(六)队列基本运算

①初始化队列initQueue(Q):创建一个空队列Q。

②判队空isEmpty(Q):当队列为空时返回“真"值,否则返回“假"值。

③入队enQueue(Q,x):将元素x加入到队列Q的队尾,并更新队尾指针。

④出队deQueue(Q):将队头元素从队列Q中删除,并更新队头指针。

⑤读队头元素frontQueue(Q):返回队头元素的值,但不更新队头指针。

(七)队列存储结构


存储结构

说明

1

队列的顺序存储

又称顺序队列。

利用一组地址连续的存储单元存放队列中的元素。

队中元素的插入和删除限定在表的两端进行,设置队头和队尾指针,分别指示出当前队首元素和队尾元素。

2

队列的链式存储

也称链队列。

给链队列添加一个头结点,并令头指针指向头结点,队列为空的判定条件是头指针和尾指针的值相同,且均指向头结点。

(八)队列应用

队列常用于处理需要排队的场合,如处理打印任务的打印队列、离散事件的计算机模拟等。