栈和队列是两种重要的线性结构。
从数据结构来看,栈和队列也是线性表,只不过是操作受限的线性表;
从数据类型来看,栈和队列是不同于线性表的两类重要的抽象数据类型。
栈和队列作为特殊的线性表,其特殊性在于它们的基本操作是线性表操作的一个子集。
栈 | 队列 | |
定义 | 只能在一端进行插入和删除操作的线性表。 该操作端为线性表的表尾,称之为栈顶(top),栈的另一端称之为栈底(bottom) 栈的第一个数据元素称之为栈顶元素 当栈中没有数据元素时称为空栈 栈的插入操作被形象地称为进栈或入栈(push),删除操作称为出栈或退栈(pop) | 简称队,它只允许在表的一端插入元素,而在另一端删除元素。 允许插入元素的一端称之为队尾,允许删除数据的一端称之为队头。 向队列中插入新的数据元素称之为入队,新的元素入队后就成为队列的队尾元素 从队列中删除队头元素称为出队,队头元素出队后,其后继数据元素成为队头元素 |
特性 | 后进先出 last in first out , LIFO | 先进先出 first in first out , FIFO |
存储结构 | 主要有两种基本的存储结构:顺序存储结构和链式存储结构 分别可以用数组或单链表来实现 | 主要有两种基本的存储结构:顺序存储结构和链式存储结构 分别可以用数组或链表来实现 |
应用 | 数制转换:如将一个十进制数N 转换为k进制数M 表达式求值 迷宫问题 实现递归 | 打印杨辉三角形 舞伴问题 |
栈的另一个重要作用,就是在程序设计语言中实现递归。
在以下三种情况下,常常要用到递归的方法:
1、函数的递归定义
有很多数学函数就是递归定义的
如 阶乘函数、二阶Fibonacci数列、幂函数和Ackerman函数等
2、数据结构的递归定义
有许多数据结构本身就是递归的,它们的操作也可以用递归来描述。
例如,单链表就是一种递归数据结构。
3、具有递归解法的问题 (如 八皇后问题、Hanoi塔问题 等)
递归的应用举例:求n的阶乘 ,汉诺塔问题
顺序队列之 “假溢出” :
随着队列中某些数据元素的出队,数组前面会出现一些空闲单元,而尾指针已经达到队列的最大长度。
这个时候,如果有新的数据元素想要入队,也不能插入。
实际队列所用的存储空间并没有真正“被占满” ,这种现象就叫做“假溢出” 。
解决“假溢出”现象,使得队列的存储空间得到充分利用:
由于“假溢出”是顺序队列进行队头出队、队尾入队的操作造成的。
一个较巧妙的办法就是将顺序队列的数组看成一个头尾相接的循环结构,可称为循环队列。
其中,队头、队尾指针与队列中的数据元素之间的关系保持不变。
当出现上述“假溢出”的情况时,可以是尾指针或头指针退回到 0 的位置 。这样,如果队列的头部有空闲空间,则可继续进行入队操作。
共同学习,共同进步,若有补充,欢迎指出,谢谢!