栈和队列
栈的定义:栈是限定仅在表尾进行插入或删除操作的线性表。表尾端称为栈顶 表头端称为栈底 不含元素的空表称为空栈
特点:栈的修改是按后进先出的原则进行的
顺序栈的表示和实现
定义:顺序栈是指利用顺序存储结构实现的栈。即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,以top指示栈顶元素指针 以base指示栈底元素指针
空栈:当top和base相等时表示空栈。
栈中元素个数:top-base;
原理:当插入新栈顶元素时,指针top增加1,删除栈顶元素时指针top减1。栈非空时,top始终指向栈顶元素的上一个位置。
`//////--------顺序栈的存储结构------------
#define Maxsize 100 ////顺序栈存储空间的初始分配量
typedef struct
{ SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //栈可用的最大容量
} SqStack;`
`///----------顺序栈的初始化------------
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;
}`
`///-------顺序栈的入栈操作----------
Status Push(SqStack &s,SElemType e)
{ ///插入元素e为新的栈顶元素
if(S.top-S.base==S.stacksize) return error; ///栈满
*S.top=e;
S.top++; ///元素e压入栈顶 栈顶指针加一
return ok;
} `
`///-------顺序栈的出栈操作----------
Status Pop(SqStack &s,SElemType &e)
{ ///删除栈顶元素用e返回其值
if(S.top==S.base) return error; ///栈空
S.top--;
e=*S.top; ///栈顶指针减一,将栈顶元素赋给e
return ok;
} `
`////------取顺序栈的栈顶元素-----------
SElemType GetTop(SqStack S)
{ ///返回S的栈顶元素 不修改栈顶指针
if(S.top!=S.base) ///栈非空
return *(S.top-1); ///返回栈顶元素的值 栈顶指针不变
}`
链栈的表示和实现
定义:链栈指采用链式存储结构实现的栈 通常链栈用单链表表示
`////-------链栈的存储结构------
typedef struct StackNode
{
ElemType data; ////链栈的数据域
struct StackNode *next; ///链栈的指针域
}StackNode,*LinkStack;`
`/////------链栈的初始化--------
Status InitStack(LinkStack &s)
{ ///构造一个空栈S,栈顶指针置空
S=NUll;
return ok;
}`
`//////-------链栈的入栈-----
Status Push (LinkStack &s,SElemType e)
{ ///在栈顶插入元素e
p=new StackNode; //生成新节点
p->data=e; ///将新结点数据域置为e
p->next=S; ///将新结点插入栈顶
S=p; ///修改栈顶指针为p
return ok;
}`
`/////--------链栈的出栈--------
Status Pop(LinkStack &s,SElemType &e)
{ //删除S的栈顶元素,用e返回其值
if(S==NULL) return error; //栈空
e=S->data; //将栈顶元素赋给e
p=S; //用p临时保存栈顶元素空间,以备释放
S=S->next; ///修改栈顶指针
delete p; /// 释放原栈顶元素的空间
return ok;
}`
`////------取链栈的栈顶元素-------
SElemType GetTop(LinkStack S)
{ //返回S的栈顶元素,不修改栈顶的指针
if(S!=NULL) //栈非空
return S->data; //返回栈顶元素值,栈顶指针不变
}`
栈与递归
1.认识递归:栈的重要应用是在程序设计语言中实现递归,所谓递归指若在一个函数过程或者数据结构定义的内部又直接(或间接)出现定义的本身的应用称它们时递归的或者是递归定义的。
利用栈将递归转换为非递归的方法步骤:
(1)设置一个工作栈存放递归工作记录(包括实参 返回地址及局部变量)
(2) 进入非递归调用入口将调用程序传来的实在参数和返回地址入栈
(3) 进入递归调用入口:当不满足递归结束条件时 逐层递归将实参返回地址及局部变量入栈 这一个过程可以用循环语句实现
(4)递归结束条件满足 将到达递归出口的给定常数作为当前的函数值
(5) 在栈不空的情况下,逐层计算当前的函数值,直至栈空为止。