当前位置:文档之家› 数据结构实验—栈及其应用

数据结构实验—栈及其应用

《算法与数据结构》课程实验报告一、实验目的1.熟悉栈的特点(先进后出)及栈的基本操作,如入栈、出栈等,掌握栈的基本操作在栈的顺序存储结构。

2.实现栈的顺序存储结构,通过实验深入理解栈的操作特点。

二、实验内容及要求1.实现栈的存储结构及相关操作:进栈、出栈、取栈顶元素等。

2.使用该栈完成对一个字符串的逆序输出。

3.使用该栈完成判断表达式的括号是否匹配。

4.对算术表达式求值。

三、系统分析(1)数据方面:该栈数据元素类型采用浮点型,在此基础上进行栈的基本操作,并可将栈中数据使用文本文档保存。

在栈的应用中,采用的是存储字符元素类型的栈,并进行对字符的相关操作。

(2)功能方面:能实现栈的一些基本操作,主要包括:1.进栈操作:若栈不满,则将元素x插入至栈的栈顶,若栈满则进行溢出处理。

2.出栈操作:若栈不空,则函数返回该栈栈顶的元素,并且栈顶指针退1。

3.获取栈顶元素:若栈不空,则函数返回栈顶元素。

4.判断栈是否为空、判断栈是否满。

5.计算栈中元素个数:直接返回栈中元素个数。

6.清空栈内容:将栈顶指针赋为初始值。

7.保存数据:将栈中元素数据保存至文本文档中。

四、系统设计(1)设计的主要思路顺序栈可以采用顺序表作为其存储表示,为此,在顺序栈的声明中用顺序表定义它的存储空间。

存放栈元素的数组的头指针为*elements,该数组最大能允许存放元素个数为maxSize,当前栈顶位置由数组下标指针top知识。

并规定如果栈不空时,elements[0]为栈中第一个元素。

由于实验中还需完成栈的相关应用,故使用两个菜单分别完成栈的基本操作与栈的应用调试。

(2)数据结构的设计顺序栈定义为只允许在表的末端进行插入和删除的线性表。

允许插入和删除的一端叫做栈顶,而不允许插入和删除的另一端叫做栈底。

当栈中没有任何元素时则成为空战。

即栈又被称为后进先出的线性表,故与线性表的相关操作类似,在此基础上完成栈的相关操作及应用。

数据结构设计思路(3)基本操作的设计栈的基本操作主要包括进栈、出栈、弹出栈顶元素等。

主要难点是在栈相关应用的实现。

第一个应用即是通过栈的操作实现括号匹配。

思路则是依次扫描输入字符串,将左括号存放至栈中,后续扫描遇到右括号则与之相匹配,同时在栈顶删除左括号。

最后将括号匹配信息输出。

在实现栈进行表达式计算过程稍微复杂。

先编写一个Calculator类,该类实现表达式计算的进操作数、退操作数等操作,在主函数文件中编写将中缀表达式转为后缀表达式函数,将转化后的表达式在进行计算即可。

算法主要思路为:顺序扫描表达式每一项,如果是操作数则进行压栈,为操作符则弹出两个操作数,并进行指令运算,将结果再次压入栈中,处理完后,将结果输出即可。

由于为了实现多为操作数的计算故需作出相应改进,用一个字符串保存输入的表达式,在通过字符串操作将操作数和操作符保存至一个字符串数组中,再通过栈的操作将其转为后缀表达式并存放至字符串数组中,在在字符串数组的基础上进行表达式值得计算。

该函数可计算操作数为双精度的表达式。

五、编程环境与实验步骤(1)编程环境操作系统:Windows操作系统;编程工具软件:Visual Studio 2017(2)实验步骤程序相关文件为SeqStack模板类文件、Calculator类文件、以及主函数调试文件main.cpp。

Calculator类文件在栈应用操作中实现表达式相关计算,SeqStack 模板类文件包括栈的相关操作,例如进栈、出栈等操作。

主函数调试文件则是用于调试栈的基本操作,并且添加了相关栈应用的相关函数,可通过两个菜单的关联,完成栈的基本操作以及相关应用的实现。

(3)编译参数无编译参数,在Vs2017或其他版本中新建项目然后将三个文件main.cpp、Calculator.h、SeqStack.h添加到解决方案中的头文件中调试即可。

六、实现代码#include<iostream>#include"Calculator.h"#include<string>using namespace std;const int maxLength = 100; //最大匹配字符串长度int isp(char &a);//栈内优先数int icp(char &a);//栈外优先数void PrintMatchedPairs(char *expression);//栈的应用——括号匹配void postfix();//栈的应用——中缀表达式转化为后缀表达式void inverse(char *c);//栈的应用——字符串逆序输出void menu1();//栈的基本操作菜单void menu2();//栈的应用菜单string str2[1000];//用于存放中缀表达式int number = 0;//用于表示表达式中数据个数int main() {int fini = 0; int choose;while (!fini) {cout <<"***************************************"<< endl;cout <<"-----------1、栈的基本操作-------------"<< endl;cout <<"-----------2、栈的应用-----------------"<< endl;cout <<"-----------3、退出---------------------"<< endl;cout <<"***************************************"<< endl;cout <<"请输入你的选择[1-3]:"<< endl;cin >> choose;switch (choose) {case 1:menu1();break;case 2:menu2();break;case 3:fini = 1;break;default:cout <<"输入选择错误,请重新输入!"<< endl;}}return 0;}int isp(char &a) {switch (a) {case'#':return 0; break;case'(':return 1; break;case'*':case'%':case'/':return 5; break;case'+':case'-':return 3; break;case')':return 6; break;}}int icp(char &a) {switch (a) {case'#':return 0; break;case'(':return 6; break;case'*':case'%':case'/':return 4; break;case'+':case'-':return 2; break;case')':return 1; break;}}void PrintMatchedPairs(char *expression) {SeqStack<int> s(maxLength);int j, length = strlen(expression);for (int i = 1; i <=length; i++) {if (expression[i - 1] == '(')s.Push(i);else if (expression[i - 1] == ')') {if (s.Pop(j) == true)cout << j <<"与"<< i <<"匹配"<< endl;elsecout <<"没有与第"<< i <<"个右括号匹配的左括号!"<< endl;}}while (s.IsEmpty() == false) {s.Pop(j);cout <<"没有与第"<< j <<"个左括号匹配的右括号!"<< endl;}}void postfix() {SeqStack<char> s;char ch = '#';s.Push(ch);string str ; //用于存放表达式string num = "";//用于存放有多位的操作数cout <<"请输入表达式:"<< endl; cin >> str;for (int i = 0; i < str.length(); i++){if (str[i] == '0' || str[i] == '1' || str[i] == '2' || str[i] == '3' || str[i] == '4' || str[i] == '5' || str[i] == '6' || str[i] == '7' || str[i] == '8' || str[i] == '9' || str[i] == '.') {num = num + str[i];}else {char ch1;str2[number] = num; number++; num ="";s.getTop(ch1);if (isp(ch1) < icp(str[i])) {s.Push(str[i]);}else if (isp(ch1) > icp(str[i])) {char op;s.Pop(op);if (op != '(') {str2[number] = op; number++; i--;}}else {char ch3;s.Pop(ch3);}}}if (num !="") {str2[number] = num; number++; num ="";}while (!s.IsEmpty()){char ch4; s.Pop(ch4); str2[number] = ch4; number++;}}void inverse(char *c) {SeqStack<char> s; int i = 0; char ch;int l = strlen(c);for (int i = 0; i < l; i++)s.Push(c[i]);for (int i = 0; i < l; i++) {s.Pop(ch);cout << ch <<" ";}}void menu1() {int fini = 0; int choose;SeqStack<double> s;double x;//压栈元素double y;//存储出栈元素double z;//存储栈顶元素while (!fini) {cout <<"-----------一、栈的基本操作-------------"<< endl;cout <<"-----------1:进栈操作-------------------"<< endl;cout <<"-----------2:出栈操作-------------------"<< endl;cout <<"-----------3:读取栈顶元素---------------"<< endl;cout <<"-----------4:判断栈是否空---------------"<< endl;cout <<"-----------5:判断栈是否满---------------"<< endl;cout <<"-----------6:计算栈中元素个数-----------"<< endl;cout <<"-----------7:清空栈的内容---------------"<< endl;cout <<"-----------8:文件保存栈中元素-----------"<< endl;cout <<"-----------9:退出:---------------------"<< endl;cout <<"****************************************"<< endl;cout <<"请输入你的选择[1-9]:"<< endl;cin >> choose;switch (choose) {case 1:cout <<"输入进栈数:"<<endl;cin >> x;s.Push(x);break;case 2:s.Pop(y);cout <<"弹出元素是:"<< y << endl;break;case 3:s.getTop(z);cout <<"此时栈顶元素为:"<< z << endl;break;case 4:if (s.IsEmpty())cout <<"栈为空!"<< endl;elsecout <<"栈不为空!"<< endl;break;case 5:if(s.IsFull())cout <<"栈满!"<< endl;elsecout <<"栈不满!"<< endl;break;case 6:cout <<"此时栈中有"<< s.getSize() <<"个元素"<< endl;break;case 7:s.MakeEmpty();cout <<"栈被清空"<< endl;case 8:s.SaveFile();cout <<"保存成功!(数据由顶至底)"<< endl;cout <<"此时栈被清空!"<< endl;break;case 9:fini = 1;break;default:cout <<"输入选择错误,请重新输入!"<< endl;}}}void menu2() {int fini = 0; int choose;char c[maxLength];//输入字符串double x;Calculator ca(stackIncreament);while (!fini) {cout <<"-----------二、栈的应用-----------------"<< endl;cout <<"-----------1:括号匹配-------------------"<< endl;cout <<"-----------2:表达式的计算---------------"<< endl;cout <<"-----------3:字符串逆序输出-------------"<< endl;cout <<"-----------4:退出:---------------------"<< endl;cout <<"****************************************"<< endl;cout <<"请输入你的选择[1-4]:"<< endl;cin >> choose;switch (choose) {case 1:cin.get();cin.getline(c,maxLength);PrintMatchedPairs(c);break;case 2:postfix();ca.Run(x);cout << x << endl;break;case 3:cin.get();cin.getline(c, maxLength);cout <<"字符串逆序输出:"<< endl;inverse(c);cout << endl;break;case 4:fini = 1;break;default:cout <<"输入选择错误,请重新输入!"<< endl;}}}七、测试结果与说明栈的基本操作:进栈与出栈:进栈与读取元素:栈中元素个数:栈空或满:保存数据:栈的相关应用:字符串中括号匹配:字符串逆序输出:表达式计算:八、实验分析(1)算法的性能分析栈的括号匹配算法分析。

相关主题