第三章 栈和队列

来源:互联网 发布:java后端是干什么的 编辑:程序博客网 时间:2024/05/14 11:08

 

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  Queue 
Data
   
队列中元素具有相同类型及先进先出特性,

   
相邻元素具有前驱和后继关系
Operation
     InitQueue
       
前置条件:队列不存在
       
输入:无
       
功能:初始化队列
       
输出:无
       
后置条件:创建一个空队列

初始化

:

  

初始化运算是将栈顶初始化为

0


 DestroyQueue
     
前置条件:队列已存在
     
输入:无
     
功能:销毁队列
     
输出:无
     
后置条件:释放队列所占用的存储空间
 EnQueue 
     
前置条件:队列已存在
     
输入:元素值x
     
功能:在队尾插入一个元素

     
输出:如果插入不成功,抛出异常
     
后置条件:如果插入成功,队尾增加了一个元素

初始化

:

  

初始化运算是将栈顶初始化为

0


DeQueue 
     
前置条件:队列已存在
     
输入:无
     
功能:删除队头元素
     
输出:如果删除成功,返回被删元素值
     
后置条件:如果删除成功,队头减少了一个元素
 GetQueue
     
前置条件:队列已存在
     
输入:无
     
功能:读取队头元素
     
输出:若队列不空,返回队头元素
     
后置条件:队列不变

初始化

:

  

初始化运算是将栈顶初始化为

0


Empty 
     
前置条件:队列已存在
     
输入:无
     
功能:判断队列是否为空
     
输出:如果队列为空,返回1,否则,返回0
     
后置条件:队列不变

endADT

3.2.2

初始化

:

  

初始化运算是将栈顶初始化为

0

   队列的顺序存储结构及实现

初始化

:

  

初始化运算是将栈顶初始化为

0

循环队列:将存储队列的数组头尾相接。

方法二:修改队满条件,浪费一个元素空间,队满时数组中只有一个空闲单元;
方法三:设置标志flag,当front=rearflag=0时为队空,当front=rearflag=1时为队满。

1)构造函数

2入队操作

3)出队操作

4)读取队头元素

5)判空操作

3.2.3循环队列和链队列的比较

初始化

:

  

初始化运算是将栈顶初始化为

0


时间性能:
循环队列和链队列的基本操作都需要常数时间O (1)

初始化

:

  

初始化运算是将栈顶初始化为

0


空间性能:
循环队列:必须预先确定一个固定的长度,所以有存储元素个数的限制和空间浪费的问题。

链队列:没有队列满的问题,只有当内存没有可用空间时才会出现队列满,但是每个元素都需要一个指针域,从而产生了结构性开销。

初始化

:

  

初始化运算是将栈顶初始化为

0

0 0