一、栈的定义 

栈是一种只能在一端进行插入或删除操作的线性表

表中允许进行插入、删除操作的一端称为栈顶。表的另一端称为栈底

栈顶的当前位置是动态的,栈顶的当前位置由一个称为栈顶指针的位置指示器指示。

当栈中没有数据元素时,称为空栈

栈的插入操作通常称为进栈或入栈,栈的删除操作通常称为退栈或出栈

栈的主要特点是“后进先出”,即后进栈的元素先出栈。栈也称为后进先出表。

栈的几种基本运算如下:    

InitStack(&s):初始化栈。构造一个空栈s。
DestroyStack(&s):销毁栈。释放栈s占用的存储空间。
StackEmpty(s):判断栈是否为空:若栈s为空,则返回真;否则返回假。
Push(&S,e):进栈。将元素e插入到栈s中作为栈顶元素。
Pop(&s,&e):出栈。从栈s中退出栈顶元素,并将其值赋给e。

GetTop(s,&e):取栈顶元素。返回当前的栈顶元素,并将其值赋给e。

二、栈的顺序存储结构及其基本运算实现   

假设栈的元素个数最大不超过正整数MaxSize,所有的元素都具有同一数据类型ElemType

则可用下列方式来定义栈类型SqStack:

typedef struct 
{  ElemType data[MaxSize]; 
   int top; //栈顶指针

} SqStack;

顺序栈4要素:

栈空条件:top=-1
栈满条件:top=MaxSize-1
进栈e操作:top++; 将e放在top处

退栈操作:从top处取出元素e; top--;

(1)初始化栈initStack(&s)

   建立一个新的空栈s,实际上是将栈顶指针指向-1即可。对应算法如下:

 void InitStack(SqStack *&s)
  {  s=(SqStack *)malloc(sizeof(SqStack));
     s->top=-1;

  } 

(2)销毁栈ClearStack(&s)

释放栈s占用的存储空间。对应算法如下:    

void DestroyStack(SqStack *&s)
{
  free(s);

}

(4)进栈Push(&s,e)

 在栈不满的条件下,先将栈指针增1,然后在该位置上插入元素e。对应算法如下:    

bool Push(SqStack *&s,ElemType e)
{
  if (s->top==MaxSize-1)  //栈满的情况,即栈上溢出
return false;
   s->top++;    //栈顶指针增1
   s->data[s->top]=e;    //元素e放在栈顶指针处
   return true;

}

(5)出栈Pop(&s,&e)

在栈不为空的条件下,先将栈顶元素赋给e,然后将栈指针减1。对应算法如下:    

bool Pop(SqStack *&s,ElemType &e)
{
   if (s->top==-1) //栈为空的情况,即栈下溢出
return false;
   e=s->data[s->top]; //取栈顶指针元素的元素
   s->top--; //栈顶指针减1
   return true;

}

(6)取栈顶元素GetTop(s)

在栈不为空的条件下,将栈顶元素赋给e。对应算法如下:

bool GetTop(SqStack *s,ElemType &e)
{
   if (s->top==-1) //栈为空的情况,即栈下溢出    
      return false;
    e=s->data[s->top]; //取栈顶指针元素的元素
    return true;

}

三、栈的链式存储结构及其基本运算的实现   

采用链式存储的栈称为链栈,这里采用单链表实现。

链栈的优点是不存在栈满上溢的情况。这里规定栈的所有操作都是在单链表的表头进行的,用带头节点的单链表表示链栈,第一个数据节点是栈顶节点,最后一个节点是栈底节点,栈中元素自栈顶到栈底依次是a1、a2、…、an。

链栈的4要素:

栈空条件:s->next=NULL
栈满条件:不考虑
进栈e操作:将包含e的节点插入到头节点之后

退栈操作:取出头节点之后节点的元素并删除之

链栈中数据节点的类型LiStack定义如下:  

typedef struct linknode
{  ElemType data; //数据域
   struct linknode *next; //指针域

} LiStack;

链栈和链表很类似,只是在进栈和出栈时略有不同:

(1)进栈Push(&s,e)

将新数据节点插入到头节点之后。对应算法如下:  

void Push(LiStack *&s,ElemType e)
{  LiStack *p;
   p=(LiStack *)malloc(sizeof(LiStack));
   p->data=e; //新建元素e对应的节点*p
   p->next=s->next; //插入*p节点作为开始节点
   s->next=p;

}

(2)出栈Pop(&s,&e)

在栈不为空的条件下,将头节点后继数据节点的数据域赋给e,然后将其删除。对应算法如下:  

bool Pop(LiStack *&s,ElemType &e)
{  LiStack *p;
   if (s->next==NULL) //栈空的情况
return false;
   p=s->next; //p指向开始节点
   e=p->data;
   s->next=p->next; //删除*p节点
   free(p); //释放*p节点
   return true;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值