湖南大学数据结构实验
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HUNAN UNIVERSITY
数据结构实验报告
题目:实验5四则运算表达式求值
学生姓名谢毅学生姓名冯吉禹学生姓名吕志远学生学号20110806109学生学号20110806110学生学号20110806114
专业班级信息安全1101班
指导老师夏艳
完成日期2013 年04 月 19日
一.需求分析
1、利用二叉树后序遍历来实现表达式的转换,同时可以使用实验3的结果来求解后缀表达式的值。
2、输入输出格式:
输入:在字符界面上输入一个中缀表达式,回车表示结束。
输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。
输入:21+23*(12-6)
输出:21 23 12 6 -*+
一.概要设计
抽象数据类型
1.使用二叉树来实现
2.本程序包含四个基本模块
①主程序模块:建树的过程
②没有括号时的输入
③有括号时的输入
○4后序输出
三﹑算法(C++)
物理数据类型
建树的时候对于优先级比较高的符号最为子结点插入,对于优先级比较低的则作为父结点插入,数据直接插入在字符的左右子结点位置。
/*问题描述
四则运算表达式求值,将四则运算表达式用中缀表达式,然后转换为后缀表达式,并计算结果。
基本要求
使用二叉树来实现。
实现提示
利用二叉树后序遍历来实现表达式的转换,同时可以使用实验3的结果来求解后缀表达式的值。
输入输出格式:
输入:在字符界面上输入一个中缀表达式,回车表示结束。
输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;
如果不正确,在字符界面上输出表达式错误提示。
*/
#include<iostream.h>
#include <stdio.h>
/*
二叉树的节点类
*/
class Node
{
public:
int num;//元素
char c;//操作符
Node* lc;//左指针
Node* rc;//右指针
Node* pa;//父指针
Node(int num,Node* lc=NULL,Node* rc=NULL)
{
this->num=num;
this->lc=lc;
this->rc=rc;
}
Node(char c,Node* lc=NULL,Node* rc=NULL)
{
this->c=c;
this->lc=lc;
this->rc=rc;
}
bool isLeaf()
{
return (lc==NULL)&&(rc==NULL);
}
};
void Nomal(char &t,char &c,Node* &one,Node* &two);//正常输入void UNomal(char &t,char &c,Node* &one,Node* &two);//带括号输入void BHVisit(Node* root);
/*
二叉树类
*/
class TwoTree
{
private:
Node* root;//根节点
Node* present;//当前表达式节点
public:
TwoTree()
{
root=NULL;
present=root;
}
Node* getroot()
{
return root;
}
bool gt(Node* two,Node* present)//比较优先级的函数
{
char ct=two->c;
char cp=present->c;
if(ct=='*'||ct=='/')
if(cp=='+'||cp=='-')
return true;
return false;
}
void insert(Node* one,Node* two=NULL)//向插入的方法
{
cout<<" 要插入了 "<<one->num<<" "<<two->c<<endl;
if(root==NULL)
{
root=two;
root->lc=one;
one->pa=root;
present=root;
return;
}
if(two->c=='\n')
{
present->rc=one;
one->pa=present;
return;
}
if(gt(two,present))//如果输入的操作符的优先等级大于当前指针的优先级
{
two->lc=one;
one->pa=two;
present->rc=two;
two->pa=present;
present=two;
return;
}
present->rc=one;
while(!gt(two,present)&&present!=root)//如果输入的操作符的优先等级不大于当前指针的优先级
{
present=present->pa;//指向父节点
}
if(gt(two,present))//如果输入的操作符的优先等级大于当前指针的优先级
{
two->lc=present->rc;
present->rc->pa=two;
present->rc=two;
two->pa=present;
present=two;
return;
}else
{
two->lc=present;
present->pa=two;
root=two;
present=two;
}
}
};
void main()
{
TwoTree tt;
Node* root;
Node* one;
Node* two;
char c,t;
int index=0;
cout<<"请输入一个中缀表达式"<<endl;
while(1)
{
t=getchar();
cout<<t<<endl;
if(t!='(')
Nomal(t,c,one,two);
else
UNomal(t,c,one,two);
tt.insert(one,two);
if(c=='\n')
break;
}
root=tt.getroot();
BHVisit(root);
return;
}
void Nomal(char &t,char &c,Node* &one,Node* &two) {
int num;
num=t-'0';
cout<<num<<"--------"<<endl;
c=getchar();
one=new Node(num);
two=new Node(c);
}
void UNomal(char &t,char &c,Node* &one,Node* &two) {
int num;
TwoTree ttp;
while(1)
{
t=getchar();
num=t-'0';
cout<<num<<"+++++++++++"<<t<<endl;
c=getchar();
if(c==')')
{
char cp='\n';
c=getchar();
one=new Node(num);
two=new Node(cp);
ttp.insert(one,two);
break;
}
one=new Node(num);
two=new Node(c);
ttp.insert(one,two);
}
one=ttp.getroot();
two=new Node(c);
}
void BHVisit(Node* root)//后序遍历函数
{
if(root==NULL)
return;
BHVisit(root->lc);
BHVisit(root->rc);
if(root->isLeaf())
cout<<root->num<<" ";
else
cout<<root->c<<" ";
}
六.算法的时间复杂度:
整个程序的时间复杂度是O(n).
七.实验心得
谢毅:本次实验相对上次实验来说难度提升比较大,刚开始的时候觉得无从下手,后来翻阅了书上的关于树的内容,并且和同学们经过了讨论,终于想出了这次实验的建树方式。
不过对于实验中括号的处理更是一个比较困难的部分,不过后来通过小组成员的努力,终于解决了这个难题。
吕志远:这个实验的确有一定的难度,以至于开始学代码时无从下手。
后来,经过对树的具体形状和功能的构思才有了思路。
经过多次修改和调试才实现了没有括号输入情况下的功能,但,处理括号用了很长的时间,才成功。
冯吉禹:这次的试验难度比较大,我们小组提前了半天开始准备这道题,通过讨论找出的解决方法。
建树的方式思考了比较久的时间,在助教老师的指导下通过VC的调试一步一步寻找代码出问题的地方。