数据结构之堆栈

 栈和队列是两种应用非常广泛的数据结构,它们都来自线性表数据结构,都是“操作受限”的线性表。
栈在计算机的实现有多种方式:
◆ 硬堆栈:利用CPU中的某些寄存器组或类似的硬件或使用内存的特殊区域来实现。这类堆栈容量有限,但速度很快;

◆ 软堆栈:这类堆栈主要在内存中实现。堆栈容量可以达到很大。在实现方式上,又有动态方式和静态方式两种。


栈的概念:
   栈(Stack):是限制在表的一端进行插入和删除操作的线性表。又称为后进先出LIFO (Last In First Out)或先进后出FILO (First In Last Out)线性表。
   栈顶(Top):允许进行插入、删除操作的一端,又称为表尾。用栈顶指针(top)来指示栈顶元素。
   栈底(Bottom):是固定端,又称为表头。
   空栈:当表中没有元素时称为空栈。

栈的抽象数据类型定义
ADT Stack{
数据对象:D ={ ai|ai∈ElemSet,  i=1,2,…,n,n≥0 }
数据关系:R ={<ai-1, ai>|ai-1,ai∈D,  i=2,3,…,n }
基本操作:初始化、进栈、出栈、取栈顶元素等
} ADT Stack


栈的顺序存储表示

   栈的顺序存储结构简称为顺序栈,和线性表相类似,用一维数组来存储栈。根据数组是否可以根据需要增大,又可分为静态顺序栈和动态顺序栈。
◆ 静态顺序栈实现简单,但不能根据需要增大栈的存储空间;
◆ 动态顺序栈可以根据需要增大栈的存储空间,但实现稍为复杂。

栈的动态顺序存储表示:

     采用动态一维数组来存储栈。所谓动态,指的是栈的大小可以根据需要增加。
◆ 用bottom表示栈底指针,栈底固定不变的;栈顶则随着进栈和退栈操作而变化。用top(称为栈顶指针)指示当前栈顶位置。
◆ 用top=bottom作为栈空的标记,每次top指向栈顶数组中的下一个存储位置。
◆ 结点进栈:首先将数据元素保存到栈顶(top所指的当前位置),然后执行top加1,使top指向栈顶的下一个存储位置;

◆ 结点出栈:首先执行top减1,使top指向栈顶元素的存储位置,然后将栈顶元素取出。


栈的类型定义
#define  STACK_SIZE  100                           /*  栈初始向量大小  */
#define STACKINCREMENT 10                 /*  存储空间分配增量  */
#typedef  int  ElemType ;
typedef struct sqstack
{   ElemType  *bottom;               /*  栈不存在时值为NULL  */
ElemType  *top;                       /*  栈顶指针  */
int   stacksize ;                          /*  当前已分配空间,以元素为单位  */
}SqStack ;


栈的初始化
Status Init_Stack(void)
{      

 SqStack  S ;
S.bottom=(ElemType *)malloc(STACK_SIZE *sizeof(ElemType));
if (! S.bottom) return  ERROR;
S.top=S.bottom ;                                           /*  栈空时栈顶和栈底指针相同  */
S. stacksize=STACK_SIZE; 
return OK ;
}


压栈(元素进栈)
Status push(SqStack S , ElemType  e)
   {  

if  (S.top-S.bottom>=S. stacksize-1) 
{  

  S.bottom=(ElemType *)realloc((S. STACKINCREMENT+STACK_SIZE) *sizeof(ElemType));   /*  栈满,追加存储空间  */
if (! S.bottom)  return  ERROR; 
S.top=S.bottom+S. stacksize ;
S. stacksize+=STACKINCREMENT ;
}  
*S.top=e;  S.top++ ;                                                                                         /*  栈顶指针加1,e成为新的栈顶 */
return OK;
}


弹栈(元素出栈)
Status pop( SqStack   S, ElemType  *e )                        /*弹出栈顶元素*/
{  

 if ( S.top== S.bottom )  
 return ERROR ;                  /*  栈空,返回失败标志  */
 S.top-- ; e=*S. top ;  
 return  OK ; 


栈的静态顺序存储表示;

      采用静态一维数组来存储栈。
     栈底固定不变的,而栈顶则随着进栈和退栈操作变化的,
    ◆ 栈底固定不变的;栈顶则随着进栈和退栈操作而变化,用一个整型变量top(称为栈顶指针)来指示当前栈顶位置。
    ◆ 用top=0表示栈空的初始状态,每次top指向栈顶在数组中的存储位置。 
   ◆ 结点进栈:首先执行top加1,使top指向新的栈顶位置,然后将数据元素保存到栈顶(top所指的当前位置)。

   ◆ 结点出栈:首先把top指向的栈顶元素取出,然后执行top减1,使top指向新的栈顶位置。
       若栈的数组有Maxsize个元素,则top=Maxsize-1时栈满


栈的类型定义
# define  MAX_STACK_SIZE  100      /*  栈向量大小  */
# typedef  int  ElemType ;
typedef struct  sqstack
{  

ElemType   stack_array[MAX_STACK_SIZE] ;
int  top;
}SqStack ;


栈的初始化
SqStack Init_Stack(void)
{   

 SqStack  S ;
 S.bottom=S.

          top=0 ;  

          return(S) ;

}


压栈(元素进栈)
Status push(SqStack S , ElemType  e)                                              /*  使数据元素e进栈成为新的栈顶  */
{  

if  (S.top==MAX_STACK_SIZE-1) 
return  ERROR;                                 /*  栈满,返回错误标志    */
S.top++ ;                                           /*  栈顶指针加1  */
S.stack_array[S.top]=e  ;                     /* e成为新的栈顶  */
return OK;                                                  /*  压栈成功    */
}


 弹栈(元素出栈)
Status  pop( SqStack   S, ElemType  *e )                       /*弹出栈顶元素*/
{  

if ( S.top==0 )
return ERROR ;                                                 /*  栈空,返回错误标志    */
*e=S.stack_array[S.top] ;  
S.top-- ;  
return OK ;  
}


 当栈满时做进栈运算必定产生空间溢出,简称“上溢”。上溢是一种出错状态,应设法避免。
    当栈空时做退栈运算也将产生溢出,简称“下溢”。下溢则可能是正常现象,因为栈在使用时,其初态或终态都是空栈,所以下溢常用来作为控制转移的条件。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值