3.1 栈
3.1.1栈的逻辑结构
1. 栈:限定仅在表的一端进行插入和删除操作的线性表。
允许插入和删除的一端称为栈顶,另一端称为栈底。
空栈:不含任何数据元素的栈。
栈的操作特性:后进先出
注意:栈只是对表插入和删除操作的位置进行了限制,并没有限定插入和删除操作进行的时间。
2.栈的抽象数据类型定义
ADT Stack
Data
栈中元素具有相同类型及后进先出特性,
相邻元素具有前驱和后继关系
Operation
InitStack
前置条件:栈不存在
输入:无
功能:栈的初始化
输出:无
后置条件:构造一个空栈
DestroyStack
前置条件:栈已存在
输入:无
功能:销毁栈
输出:无
后置条件:释放栈所占用的存储空间
Push
前置条件:栈已存在
输入:元素值x
功能:在栈顶插入一个元素x
输出:如果插入不成功,抛出异常
后置条件:如果插入成功,栈顶增加了一个元素
Pop
前置条件:栈已存在
输入:无
功能:删除栈顶元素
输出:如果删除成功,返回被删元素值,否则,抛出异常
后置条件:如果删除成功,栈减少了一个元素
GetTop
前置条件:栈已存在
输入:无
功能:读取当前的栈顶元素
输出:若栈不空,返回当前的栈顶元素值
后置条件:栈不变
Empty
前置条件:栈已存在
输入:无
功能:判断栈是否为空
输出:如果栈为空,返回1,否则,返回0
后置条件:栈不变
endADT
3.1.2 栈的顺序存储结构及实现
1.栈的顺序存储结构——顺序栈
(1)栈的初始化
(2)入栈操作
(3)出栈操作
(4)取栈顶元素
(5)判空操作
2.两栈共享空间
初始化
:
初始化运算是将栈顶初始化为
0
两栈共享空间:使用一个数组来存储两个栈,让一个栈的栈底为该数组的始端,另一个栈的栈底为该数组的末端,两个栈从各自的端点向中间延伸。
初始化
:
初始化运算是将栈顶初始化为
0
两栈共享空间控制类型声明const int Stack_Size=100;
template <class DataType>
class BothStack
{
public:
BothStack( );
~BothStack( );
void Push(int i, DataType x);
DataType Pop(int i);
DataType GetTop(int i);
bool Empty(int i);
private:
DataType data[Stack_Size];
int top1, top2;
};
3.1.3栈的链接存储结构及实现
初始化
:
初始化运算是将栈顶初始化为
0
1.链栈链栈:栈的链接存储结构、
初始化
:
初始化运算是将栈顶初始化为
0
2.链栈的类声明template <class DataType>
class LinkStack
{
public:
LinkStack( );
~LinkStack( );
void Push(DataType x);
DataType Pop( );
DataType GetTop( );
bool Empty( );
private:
Node<DataType> *top;
}
3.1.4顺序栈和链栈的比较
时间性能:相同,都是常数时间O(1)。
初始化
:
初始化运算是将栈顶初始化为
空间性能:顺序栈:有元素个数的限制和空间浪费的问题。
链栈:没有栈满的问题,只有当内存没有可用空间时才会出现栈满,但是每个元素都需要一个指针域,从而产生了结构性开销
。
初始化
:
初始化运算是将栈顶初始化为
0
总之,当栈的使用过程中元素个数变化较大时,用链栈是适宜的,反之,应该采用顺序栈。3.2 队列
3.2.1队列的逻辑结构
1.队列的定义
初始化
:
初始化运算是将栈顶初始化为
0
队列:只允许在一端进行插入操作,而另一端进行删除操作的线性表。允许插入(也称入队、进队)的一端称为队尾,允许删除(也称出队)的一端称为队头。
空队列:不含任何数据元素的队列。
初始化
:
初始化运算是将栈顶初始化为
0
队列的操作特性:先进先出。
初始化
:
初始化运算是将栈顶初始化为
0
队列的抽象数据类型定义
初始化
:
初始化运算是将栈顶初始化为
0
ADT QueueData
队列中元素具有相同类型及先进先出特性,
相邻元素具有前驱和后继关系
Operation
InitQueue
前置条件:队列不存在
输入:无
功能:初始化队列
输出:无
后置条件:创建一个空队列
初始化
:
初始化运算是将栈顶初始化为
0
DestroyQueue
前置条件:队列已存在
输入:无
功能:销毁队列
输出:无
后置条件:释放队列所占用的存储空间
EnQueue
前置条件:队列已存在
输入:元素值x
功能:在队尾插入一个元素
输出:如果插入不成功,抛出异常
后置条件:如果插入成功,队尾增加了一个元素
初始化
:
初始化运算是将栈顶初始化为
0
DeQueue
前置条件:队列已存在
输入:无
功能:删除队头元素
输出:如果删除成功,返回被删元素值
后置条件:如果删除成功,队头减少了一个元素
GetQueue
前置条件:队列已存在
输入:无
功能:读取队头元素
输出:若队列不空,返回队头元素
后置条件:队列不变
初始化
:
初始化运算是将栈顶初始化为
0
Empty
前置条件:队列已存在
输入:无
功能:判断队列是否为空
输出:如果队列为空,返回1,否则,返回0
后置条件:队列不变
endADT
3.2.2
初始化
:
初始化运算是将栈顶初始化为
0
队列的顺序存储结构及实现初始化
:
初始化运算是将栈顶初始化为
0
循环队列:将存储队列的数组头尾相接。 方法二:修改队满条件,浪费一个元素空间,队满时数组中只有一个空闲单元;
方法三:设置标志flag,当front=rear且flag=0时为队空,当front=rear且flag=1时为队满。
(1)构造函数
(2) 入队操作
(3)出队操作
(4)读取队头元素
(5)判空操作
3.2.3循环队列和链队列的比较
初始化
:
初始化运算是将栈顶初始化为
0
时间性能:
循环队列和链队列的基本操作都需要常数时间O (1)
初始化
:
初始化运算是将栈顶初始化为
0
空间性能:
循环队列:必须预先确定一个固定的长度,所以有存储元素个数的限制和空间浪费的问题。
链队列:没有队列满的问题,只有当内存没有可用空间时才会出现队列满,但是每个元素都需要一个指针域,从而产生了结构性开销。
初始化
:
初始化运算是将栈顶初始化为
0