数据结构复习篇:栈

二、栈

栈是一种“发育不良”的线性表,它具有与线性表相同的存储结构(基于数组的或基于链于的),但栈的“缺陷”---不能像线性表那样具有插入、删除操作---反而给了它独有的特色。在后面将会发现,递归,可以用栈来实现。 

在时间复杂度上,基于数组的栈AStack和链式栈LStack,在push()、pop()操作上,都是一个时间常数1。在我的测试中,10万次push()和10万次pop()后,基于数组的栈只比链式栈快一秒。但要注意AStack需要预先指定栈元素的最大个数,而LStack是动态分配的,元素个数在理论上不受限。

经常思考,我发现昨天在线性表那篇文章中,有一个设计错误,就是不应该把结点类Node与List类放在一个文件中,这是违反模块化思想的。当我今天的栈中要用到结点时,应该可以很轻松的通过头文件的方式把结点类引到我的代码中。以下是一个最简单的结点类界面(事实上可以采用可用空间表freelist的方式来定义结点类):

/*
定义常用于链表中的各种结点界面
文件名:NodeInterface.h
*/
#ifndef NODEINTERFACE_H
#define  NODEINTERFACE_H

template
< class  T >   class  Node     // 单端结点,只含有一个指针
{
public :
    T element;
    Node 
*  next;
public :
    Node(
const  T  & eVal, Node  *  nVal  =  NULL)
    {
        element 
=  eVal;
        next 
=  nVal;
    }
    Node(Node 
*  nVal  =  NULL)
    {
        element 
=   0 ;
        next 
=  nVal;
    }

};
#endif

以下是栈的界面及两种实现的代码:

 

  /*
 文件名:StackInterface.h
 
*/
#ifndef STACKINTERFACE_H
#define  STACKINTERFACE_H

#include 
" NodeInterface.h "

 
// 定义栈的界面
template < class  T >   class  Stack
{
public :
    
virtual   bool  push( const  T & =   0 ;     // 入栈
     virtual   bool  pop(T & =   0 ;     // 出栈
     virtual   bool  topValue(T & = 0 ;     // 栈顶元素值
};

/
// 基于数组的栈Array_based Satck
/
template < class  T >   class  AStack : public  Stack < T >
{
private :
    
int  maxSize;     // 栈最多能容纳的元素个数
     int  top;     // 指示栈中元素的实际个数,由于数组从0开始,(top-1)才指示了栈顶元素的下标
    T  *  listArray;     // array holding stack elements
public :
    AStack(
int  size  =   100 )
    {
        maxSize 
=  size;
        top 
=   0 ;
        listArray 
=   new  T[maxSize];
    }
    
~ AStack()
    {
        delete [] listArray;
    }
    
bool  push( const  T  & );
    
bool  pop(T  & );
    
bool  topValue(T  & );
    
int  length()  const
    {
        
return  top;
    }

};

template
< class  T >   bool  AStack < T > ::push( const  T  &  element)
{
    
if  (top  ==  maxSize)     // stack is full.
    {
        
return   false ;
    }
    listArray[top] 
=  element;
    
++ top;
    
return   true ;
}

template
< class  T >   bool  AStack < T > ::pop(T  &  ref_elem)
{
    
if  (top  ==   0 )     // no element in stack
    {
        
return   false ;
    }
    ref_elem 
=  listArray[ -- top];
    
return   true ;
}

template
< class  T >   bool  AStack < T > ::topValue(T  &  ref_elem)
{
    
if  (top  ==   0 )     // no element in stack
    {
        
return   false ;
    }
    ref_elem 
=  listArray[top - 1 ];
    
return   true ;
}

/ //
// 链式栈 Linked Stack
/ //
template < class  T >   class  LStack : public  Stack < T >
{
private :
    
int  listSize;     // the number of elements,and that is the number of nodes
    Node < T >   *  top;     // 与AStack栈不同,这里,top指向栈顶元素
public :
    LStack()    
// 不必限定元素的最大值
    {
        listSize 
=   0 ;
        top 
=  NULL;
    }
    
~ LStack()
    {

    }

    
bool  push( const  T  & );
    
bool  pop(T  & );
    
bool  topValue(T  & );
    
void  clear();
    
int  length()  const
    {
        
return  listSize;
    }
};    

template
< class  T >   bool  LStack < T > ::push( const  T  & element)
{
    Node
< T >   * tmp  =   new  Node < T > (element,top);
    top 
=  tmp;
    
++ listSize;
    
return   true ;
}
template
< class  T >   bool  LStack < T > ::pop(T  & ref_elem)
{
    
if  (top  ==  NULL)
    {
        
return   false ;     // 栈中没有元素
    }
    Node
< T >   * tmp  =  top;
    top 
=  top -> next;
    ref_elem 
=  tmp -> element;
    delete tmp;
    
-- listSize;
    
return   true ;

}
template
< class  T >   bool  LStack < T > ::topValue(T  &  ref_elem)
{
    
if  (top  ==  NULL)
    {
        
return   false ;     // none element in stack 
    }
    ref_elem 
=  top -> element;
    
return   true ;
}
template
< class  T >   void   LStack < T > ::clear()
{
    Node
< T >   *  tmp;
    
while  (top  !=  NULL)
    {
        tmp 
=  top;
        top 
=  top -> next;
        delete tmp;
    }
}
#endif

晚一些时候,我把用栈实现递归的方法,写到这里来。

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值