数据结构栈的实现——运用数组
Ps: 栈用类实现比较好,可以同时管理多种数据结构。不过对于刚刚接触的我来说,就看着数,按着书上的流程走吧。我会尽力把栈的特点讲解清楚,以后有了更深入的了解,我会再来补充的。
引例
逆波兰表示法 是一种将运算符写在操作数后面的描述程序(算式)的方法。举个例子,我们平常用中缀表示法描述的算式(1+2)*(5+4),改为逆波兰表示法之后则是1 2 + 5 4 - * 。相较于中缀表示法,逆波兰法的优势在于不需要括号。
请输入以逆波兰表示法输入的算式的计算结果。
输入 | 在一行中输入1个算式。相邻的符号(操作数或运算符)用一个空格符隔开 |
---|---|
输出 | 在1行之中输出计算结果 |
限制 | 2 ≤ 算 式 中 操 作 数 的 总 数 ≤ 100 2\leq算式中操作数的总数\leq100 2≤算式中操作数的总数≤100、 1 ≤ 算 式 中 运 算 符 的 总 数 ≤ 99 1\leq算式中运算符的总数\leq99 1≤算式中运算符的总数≤99 运算符仅包含“+” “-” “ ∗ * ∗”, 操作数为 1 0 6 10^6 106以下的正整数。 − 1 ∗ 1 0 9 ≤ 计 算 过 程 中 的 值 ≤ 1 0 9 -1*10^9\leq计算过程中的值\leq10^9 −1∗109≤计算过程中的值≤109 |
输入示例 | 1 2 + 3 4 - * |
输出示例 | -3 |
用C++实现
#include<iostream>
#include<string>
#include<stdlib.h>
#define MAX 1000
using namespace std;
int a[MAX], top;
int pop();
void push(int x);
int main()
{
int a, b;
top = 0;
char s[100];
while (cin >> s)
{
if (s[0] == '+')
{
a = pop();
b = pop();
push(a + b);
}
else if (s[0] == '-')
{
b = pop();
a = pop();
push(a - b);
}
else if (s[0] == '*')
{
a = pop();
b = pop();
push(a * b);
}
else
{
push(atoi(s));
//atoi函数将字符串形式的数字转化为整形数字
}
}
printf("%d\n", pop());
return 0;
}
void push(int x)
{
S[++top] = x;
}
int pop()
{
top--;
return S[top + 1];
}
问题分析
该程序用数组实现了栈,数据存在字符数组s中,每次循环将数据压入“栈”S中,top作为栈顶指针,表示最后一个添加的元素储存在S中的什么位置。每一次循环中,如果遇到字符类型数字,将转化为整形类型数字,top+1向后移位后将数字压入栈中,如果遇到运算符,top-1将其后面的数字return,取出栈中的两个元素进行运算。最终栈中剩下的数就是结果。
push(x)送来的元素在top+1后压入栈中,pop()返回top所指的元素后减1.
这只是用数组简单的实现栈,一个用数组实现的相对完整的栈应该包含如下一些的功能。
//使用数组实现栈的伪代码
initialize() //initialize函数用来清空栈
top = 0;
isEmpty() //isEmpty函数用来检查top是否为0,判断栈中是否有元素
return top == 0;
isFull() //isFull函数用判断栈中是否已满
return top >= MAX - 1;
push(x)
/*push函数将top+1后将top所指位置加入元素,
并且每次判断栈是否已满*/
if(isFull())
错误(上溢);
top++;
S[top] = x;
pop()
/*pop函数返回top所指的元素,再将top-1
并且每次判断栈是否为空*/
if(isEmpty())
错误(下溢)
top--;
return S[top+1];
一般情况下,数据结构多以结构体或类的形式实现,以类的形式实现可以同时管理多种数据结构,方便程序调用数据。