栈的表示和操作的实现

栈的抽象数据类型的类型定义

ADT Stack{
  //数据对象:
    D = {ai|ai∈ElemSet,i = 1,2,…,n,n>=0}
  //数据关系
    R1 = {<ai-1,ai>|ai-1,ai∈D,i=2,…,n}
    //约定an为栈顶,a1端为栈底
  //基本操作:初始化、进栈、出栈、取栈顶元素等
}ADT Stack

InitStack(&S)初始化操作:构造一个空栈

DestroyStack(&S)销毁栈操作:

  • 初始条件:栈S已存在
  • 操作结果:栈S被销毁

Stack Empty(S)判定S是否为空栈

  • 初始条件:栈S已存在
  • 操作结果:若栈S为空栈,则返回TRUE,否则FALSE

Stack Length(S)求栈的长度

  • 初始条件:栈S已存在
  • 操作结果:返回S的元素个数,即栈的长度

Get Top(S,&e)取栈顶元素

初始条件:栈S已存在且非空

Clear Stack(&S)栈置空操作

  • 初始条件:栈S已存在
  • 操作结果:将S清为空栈

Push(&S,e)入栈操作

  • 初始条件:栈S已存在
  • 操作结果:插入元素e为新的栈顶元素

Pop(&S,&e)出栈操作

  • 初始条件:栈S已存在且非空
  • 操作结果:删除S的栈顶元素an,并用e返回其值

顺序栈

存储方式:

同一般线性表的顺序存储结构完全相同

  • 利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,栈底一般在低地址端
  • 附设top指针,指示栈顶元素在顺序栈中的位置
  • 另设base指针,知识栈底元素在顺序栈中的位置
  • 通常top元素指示真正的栈顶元素之上的下标地址

栈空标志:

base==top

栈满:

top-base==stacksize

栈满时的处理方法:
  • 报错,返回操作系统
  • 分配更大的空间,作为栈的存储空间,将原栈的内容移入新栈
使用数组作为顺序栈存储方式的特点:

简单、方便、但易产生溢出(数组大小固定)

上溢:

栈已经满,又要压入元素

下溢:

栈已经空,还要弹出元素

注:上溢是一种错误,使问题的处理无法进行;而下溢一般认为是一种结束条件,即问题处理结束

顺序栈的表示
#define MAXSIZE 100
typedef struct {
     SElemType *base;  //栈底指针
     SElemType *top;   //栈顶指针
     int stacksize;    //栈可用最大容量
}SqStack
顺序栈的初始化
Status InitStack(SqStack &S)  //构造一个空栈
   S.base = new SElemType[MAXSIZE]; // 或
 //S.base = (SElemType*)malloc(MAXSIZE*sizeof(SElemType));
   if(!S.base) exit(OVERFLOW)  //存储分配失败
   S.top = S.base;  //栈顶指针等于栈底指针
   S.stacksize = MAXSIZE;
   return OK;
}
判断顺序栈是否为空
Statys StackEmpty(SqStack S) {
//若栈为空,返回TRUE,否则返回FALSE
   if(S.top == S.base) return TRUE;
   else return FALSE;
}
求顺序栈长度
int StackLength(SqStack S) {
   return S.top - S.base;
}
清空顺序栈
Status ClearStack(SqStack S) {
   if(S.base) S.top = S.base;
   return OK;
}
销毁顺序栈
Status DestroyStack(SqStack &S) {
   if(S.base) {
      delete S.base;  //把数组回归内存
      S.stacksize = 0;
      S.base = S.top = NULL;  //把结构类型中的三个值设置为空
   }
   return OK;
}
顺序栈的入栈

判断是否栈满,若满则出错(上溢)

元素e压入栈顶

栈顶指针+1

Status Push(SqStack &S,SElemType e) {
   if(S.top - S.base == S.stacksize)  //栈满
      return ERROR;
   *S.top++ = e;  //为*S.top = e;和S.top++;两句合并
   return OK;
}
顺序栈的出栈

判断是否栈空,若空则出错(下溢)

获取栈顶元素e

栈顶指针-1

Status Pop(SqStack &S,SElemType &e) {
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR
   if(S.top == S.base) //等价于if(StackEmpty(S))
      return ERROR;
   e = *--S.top; //为--S.top;和e = *S.top;合并
}

链栈

链栈是运算受限的单链表,只能在链表头部进行操作

typedef struct StackNode{
    SElemType data;
    struct StackNode *next;
}StackNode, *LinkStack;
LinkStack S;

  • 链表的头指针就是栈顶
  • 不需要头节点
  • 基本不存在栈满的情况
  • 空栈相当于头指针指向空
  • 插入和删除仅在栈顶处执行
链栈的初始化
void InitStack(LinkStack &S) {
    //构造一个空栈,栈顶指针置为空
    S = NULL;
    return OK;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值