第三章 栈和队列

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 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 LinkStack
{    
   public:
         LinkStack( );
         ~LinkStack( );            
         void Push(DataType x); 
         DataType Pop( ); 
         DataType GetTop( );
         bool Empty( );
   private:
         Node *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=rear且flag=0时为队空,当front=rear且flag=1时为队满。

(1)构造函数

(2) 入队操作

(3)出队操作

(4)读取队头元素

(5)判空操作

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

初始化

:

  

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

0


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

初始化

:

  

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

0


空间性能:
循环队列:必须预先确定一个固定的长度,所以有存储元素个数的限制和空间浪费的问题。
链队列:没有队列满的问题,只有当内存没有可用空间时才会出现队列满,但是每个元素都需要一个指针域,从而产生了结构性开销。

初始化

:

  

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

0

你可能感兴趣的:(第三章 栈和队列)