栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
建立
//建立
#include<stido.h>
#define size 100
typedef int ElemType;
typedef struct
{
ElemType data[size];
int top;
}SqStack;
顺序表与链表建立方法类似,建立一个栈。
结构体中定义了一个数组和栈顶。
此后的运算均基于初始栈顶指针指向0下标数据元素的位置。
初始化
//初始化
void Init(SqStack s)
{s.top=0;}
栈的初始化就是将栈顶指针的位置初始到0下标的位置。
判断栈空
bool IsEmpty(SqStack s)
{
if(s.top==o) return true;
return false;
}
判断栈空的条件是top指针的位置是否处于0下标的位置。
注意此时的函数返回值为true,函数用bool来定义。
判断栈满
//判断栈满
bool IsFull(SqStcak s)
{
if(s.top=size) return true;
return false;
}
由于size=100,所以栈中最多可容纳100个房间,所以下标的范围是0-99,第100个房间的地址即是栈满时栈顶元素的下一个位置,而size=100,故判断栈满的条件是top的位置是否在栈顶元素头上的地址,也就是下一个位置。
基本操作
1.入栈
//入栈
void Push(SqStcak &s,ElemType e)
{
if(IsFull(s)) return;
s.data[s.top]=e;
s.top++;
}
入栈操作首先要判断是否栈满。
其次将栈顶位置的房间赋值,此处注意数组下标中的top需要引用!
最后将栈顶指针上移,完成入栈操作。
2.出栈
void Pop(SqStack &s,ElemType &e)
{
if(IsEmpty (s)) return;
s.top--;
e=s.data[s.top];
}
出栈操作首先要判断是否栈空。
其次将栈顶指针下移。
最后将此时的栈顶元素赋值给e。与线性表和链表中的删除操作不同,栈的删除需要将值保留,在后面的表达式运算中可以体现。
3.读栈顶
void ReadTop(SqStack s,ElemType &e)
{
if(IsEmpty(s)) return;
e=s.data[s.top-1];
}
读栈顶元素首先判断是否栈空。
后将栈顶指针前一个房间的值赋给e元素。
4.转进制(10-8)
void Cov(int x,int y)
{ SqStack s;
Init(s);
while(x)
{
Push(s,x%y);
x=x/y;
}
while(!IsEmpty(s))
{
int e;
Pop(s,e);print("%d",e);
}
}
此函数完成十进制到八进制的转换。
首先定义一个十进制数字x,y为8。
函数内部定义一个栈,并初始化。
根据十进制与八进制转换的求余值反向罗列的规则,先将x和8求余后的余数进栈,此时下一个x应是x与8相除后的结果,故x=x/y,当x与8求余为0是停止循环。
后将栈中元素依次出栈,当栈为空时,完成进制转换操作。
代码测试
int main()
{
SqStack(s);
ElemType e;
Init(s);
for(int i=1;i<=4;i++)
Push(s,i);
ReadTop(s,e);printf("%d",e);
Pop(s,e);
Pop(s,e);printf("%d",e);
ReadTop(s,e);printf("%d\n",e);
Cov(123,8);
简单表达式计算
对于栈,可从表达式计算的角度来理解。
此算法为“算符优先法”。
对于表达式的计算我们还是依据四则运算法则,() / ± 。
例: 32/(2-4/2+7)*2
定义一个指针从数字3开始,当遇到数字时将数字保留,当遇到符号时将符号进栈,再定义一个符号栈。
计算后缀式:
首先记录3 2。
进栈,/与等级相同,*出栈,/进栈,记录 3 2 *。
( 进栈,将栈分割,此时( 为栈底,记录3 2 * 2 ,- 进栈,/进栈,/等级比 - 高,直接进入,+进栈,等级比 /
低,也和 -等级相同,故 / -依次出栈,记录 3 2 * 2 4 2 / - 7。
此时遇到),将( 上的符号依次出栈,+出栈,(出栈,()均不记录,记录3 2 * 2 4 2 / - 7 + 。
最后 碰到栈底的,*出栈/入栈,当数字记录完毕,栈中符号依次出栈。
故结果为 3 2 * 2 4 2 / - 7 + / 2 *
其次定义一个运算栈计算结果。
依次将数字入栈,当遇到符号时将栈顶数字和与他最近的数字计算(栈顶数字为运算符左边的数字,栈顶下面的数字为操作数),再入栈,最后得出结果。
结果为0。