Stack(栈)_出栈

一.基本介绍

(1)定义:栈是限定仅在表头进行插入和删除操作的线性

(2)特点:LIFO(Last In First Out->后进先出


二.分类

(一)顺序栈

I.基本介绍

Stack(栈)_栈的基本操作_02

说明:top和base在初始时均指向栈底,base指针一直指向栈底,如果有元素进栈,top就向上移动,如果有元素出栈,top指针下移。

优点:查询速度快

缺点:存储空间需要事先分配,可能会出现溢出问题


存储结构

#define MAXSIZE 100

typedef struct{

SElemType *base;       //栈底指针

SElemType *top;        //栈顶指针

int stacksize;             //栈可用的最大容量

}SqStack;

II.基本操作

初始化

Stack(栈)_栈的基本操作_03

具体代码:

Status InitStack(SqStack &S){

S.base =new SElemType[MAXSIZE];

//为顺序栈动态分配一个容量为MAXSIZE的数组空间

if(!S.base)exit(OVERFLOW);     //存储分配失败

S.top=S.base;             //top初始化为base(空栈)

S.stacksize=MAXSIZE; //stacksize置为栈的最大容量MAXSIZE

return OK;

}

入栈

Stack(栈)_出栈_04

具体代码:

Status Push(SqStack &S,SElemType e){

//插入元素e为新的元素

if(S.top-S.base=S.stacksize)  return ERROR;//栈满

*S.top++=e;              //元素e压入栈顶,栈顶指针加1

return OK;

}

出栈

Stack(栈)_入栈_05

具体代码

Status Pop(SqStack &S,SElemType &e){

if(S.top==S.base)return ERROR;//栈空

e=*--S.top;                //栈指针减1,将栈顶指针赋值给e

return OK;        

}

取栈顶

SElemType GetTop(SqStack &S){

//返回S的栈顶元素,不修改栈顶指针

if(S.top!=S.base)    //栈非空

return *(S.top-1);//返回栈顶元素的值,栈顶指针不变

}

(二) . 链栈

I.基本介绍

Stack(栈)_栈的基本操作_06

说明:结点结构和线性表的单链表的结点结构是一样的,由于栈是一种后进先出的结构,所以在存储时,新的结点的指针域指向的是上一个结点。

存储结构:

typedef struct StackNode{

ElemType data;   //数据域

struct StackNode *next;  //指针域

}StackNode,*Linktack;

II.基本操作

初始化

Stack(栈)_出栈_07

Status InitStack(){

//构造一个空栈

S=NULL;

return OK;

}

入栈

Stack(栈)_出栈_08

具体代码:

Status Push(LinkStack &S,SelemType){

//在栈顶插入元素e

p=new StackNode;    //生成新结点

p->data=e;         //初始化数据域

p->next =S;   //将新结点插入栈顶

S=p;       //修改栈顶指针为p

}

出栈

Status Pop(LinkStack &S ,SElemType &e){

//删除S的栈顶元素,用e返回其值

if(S==NULL)return ERROR;

e=S->data;

p=S;//用p临时保存栈顶元素空间,已备释放

S=S->next;//修改栈顶指针

delete p;//释放原栈顶的元素

return OK;

}

取栈顶

SElemType GetTop(LinkStack S){

if(S!=NULL)                   //栈非空

return S->data;      //返回栈顶元素的值,栈顶指针不变

}

总结:

      栈的引入简化了程序设计的问题,划分了不同关注层次,式的思考范围缩小,更加聚焦于要解决问题的核心。反之,像数组等,因为要分散精力去考虑数组的下标增减等细节问题,反而掩盖了问题的本质。

三.栈的应用

(一)递归

把一个直接调用自己或通过一系列的调用语句间接调用自己的函数,称为递归函数。

经典实例:(1)斐波那契数列

  (2)汉诺塔问题

      (3)N皇后问题

           (4)全排列

详细内容参考:https://blog.51cto.com/u_15314328/4928741



(二)四则运算表达式的求值

详细内容请参考:https://blog.51cto.com/u_15314328/5106742