您的位置:首页 > 理论基础 > 数据结构算法

【数据结构】顺序栈

2016-07-04 22:10 363 查看

  顺序栈

  (1)基本定义

   1)栈的定义:栈(stack,S)是n个元素组成的有限序列,记做S=(a₁,a₂,…),并且只能在一端插入和删除元素。当n=0时,称S为空栈

   2)栈的特性:假设向空栈中依次插入元素a₁,a₂,…后,由定义可知,删除这些元素的次序只能是…a₂,a₁。也就是说,栈具有后进先出(或先进后出,Last in,first out,LIFO)的特性

   3)栈的术语:称插入和删除元素的一端为栈顶(top),另一端为栈底(bottom)。分别称插入元素和删除元素的操作为入栈出栈,或者压栈(push)弹栈(pop)

  (2)运算的实现

 头文件:

#ifndef STACK_H//预处理器
#define STACK_H

#include <iostream>
using namespace std;

const int maxlen = 100;//栈的最大存储量

template <typename elementType>
class stack {
public:
stack();//构造函数,用于初始化(C++11新特性可以在类的声明中初始化变量)
bool empty();//判断栈是否为空
bool full();//判断栈是否为满
bool get_top(elementType &x);//取栈顶元素
bool push(elementType x);//元素入栈
bool pop();//删除栈顶
private:
int count;//元素的计数器
elementType data[maxlen];//顺序存储结构
};

template <typename elementType>
stack<elementType>::stack() {
count = 0;
}

template <typename elementType>
bool stack<elementType>::empty() {
if (count == 0)
return true;
return false;
}

template <typename elementType>
bool stack<elementType>::full() {
if (count == maxlen)
return true;
return false;
}

template <typename elementType>
bool stack<elementType>::get_top(elementType &x) {
if (!empty()) {
x = data[count - 1];
return true;
}
return false;
}

template <typename elementType>
bool stack<elementType>::push(elementType x) {
if (!full()) {
data[count++] = x;
return true;
}
return false;
}

template <typename elementType>
bool stack<elementType>::pop() {
if (!empty()) {
--count;
return true;
}
return false;
}

#endif


 (3)顺序栈的应用实例(栈在表达式计算中的应用)

 该计算器数据存储是通过声明一个栈模板,来创建一个int类型和char类型的栈。int栈存储表达式中的数字,char类型的栈存储表达式中的运算符。
  在输入表达式时,通过在表达式首尾添加“#”来使程序建立表达式的结束条件。当首尾“#”相遇时,即表达式已经计算完成,最后输出结果。
  当前源代码中只能计算+、-、*、/,以及(),可以将操作数栈改为double类型来计算浮点数。
  表达式的计算情况处理如下:
   1.如果栈顶运算符的优先级低于当前所扫描运算符的优先级,则栈顶的运算符不能计算,故当前扫描的运算符要入栈,然后继续扫描其后续符号。
   2.如果栈顶的运算符的优先级高于当前所扫描运算符的优先级,则要取出栈顶运算符进行运算。此时,栈顶运算符的两个操作数一定都在操作数栈的栈顶的两个元素中,取出这两个元素进行运算,并将运算结果再入到此栈中。
   3.如果此时的运算符栈不为空,需要继续以栈顶的运算符对当前扫描运算符重复上述比较操作,以此确定是用栈顶运算符运算还是当前扫描运算符入栈。

  源代码:

#include <iostream>
#include "stack.h"
using namespace std;

//扫描数字的函数
bool isnumber(char x) {
if (x >= '0' && x <= '9')
return true;
return false;
}

//判断运算符优先级的函数
int priority(char x) {
if (x == '+' || x == '-')
return 0;
else if (x == '*' || x == '/')
return 1;
else if (x == '(' || x == ')')
return -1;
else if (x == '#')
return -2;
}

//运算的函数
int calculate(string s) {
stack<int> number;
stack<char> operate;
char top;
int a, b;

for (unsigned int i = 0; i < s.size(); ++i) {
if (isnumber(s[i])) {
int Temp = 0;
string temp;

temp += s[i];
while (isnumber(s[++i]))
temp += s[i];
for (unsigned int j = 0; j < temp.size(); ++j) {
Temp = Temp * 10 + temp[j] - 48;
}
number.push(Temp);
temp.clear();
}//将字符数字转换成整形数字
if (!isnumber(s[i])) {
if (operate.empty()) {
operate.push(s[i]);
}//入栈第一个符号'#'
else {
operate.get_top(top);

if (priority(s[i])>priority(top) || s[i] == '(') {
operate.push(s[i]);
}//入栈高优先级的运算符
else {
while (priority(s[i]) <= priority(top)) {
if (top == '#'&&s[i] == '#') {
int answer;

operate.pop();
number.get_top(answer);
cout << "\n答案是:" << answer << endl;
number.pop();
return 0;
}//当运算符实现完全后,只剩下'#'
else if (top == '('&&s[i] == ')') {
++i;
}//当左右括号相遇时,跳过右括号,删除左括号
else {
number.get_top(a);
number.pop();
number.get_top(b);
number.pop();
}
if (top == '+') {
b += a;
number.push(b);
}
else if (top == '-') {
b -= a;
number.push(b);
}
else if (top == '*') {
b *= a;
number.push(b);
}
else if (top == '/') {
b /= a;
number.push(b);
}
operate.pop();
operate.get_top(top);//取前一个运算符,用于与现在扫描的运算符进行比较
}//将优先级高的运算符实现计算
operate.push(s[i]);//用于当top=='#'时,将最后一个运算符入栈
}
}
}//扫描运算符,并判断优先级,以及运算
}//主循环
}//对运算符的扫描,和数字字符的转化,以及计算

int main() {
string expression;
cout << "输入一个用'#'开头和结尾的表达式:" << endl;
cin >> expression;
calculate(expression);
cin.get(), cin.get();
}


 代码运行截图:

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息