1、 HUNAN UNIVERSITY 课程实习报告 题 目: 四则运算表达式求值 学生姓名 康小雪 学生学号 20090810310 专业班级 计科三班 指导老师 李晓鸿 完 成 日 期 2010-10—24
2、 一、 需求分析 1.该程序可以从通过从键盘输入一个中缀表达式,判断该表达式是否合法,若合法将 其转化为后缀表达式,并计算其结果,否则说明该表达式错误 2.。输入的表达式包含数字和运算符及括号,之间用空格隔开 3.数字可以为整数和小数 4.运算结果保留两位小数 输入输出举例 输入:21+23*(12-6) 输出:21 23 12 6 —*+ 二、 概要设计 在表达式中每个运算符应对应两个操作数,与二叉树中非叶子结点和叶子结点之间的关系刚好相同,于是,本题可采用二叉树来将中缀表达式变为后缀表达式.
3、
最后用堆栈来实现后缀表达式的计算.
抽象数据类型
二叉树
ADT BiTree
{
数据对象 D:D是具有相同特性的数据元素集合
数据关系 R:
若D为空集,则R为空集,则称BinaryTree为空二叉树;
若D不为空集,否则R={H},H是如下二元关系:
(1) 在D中存在唯一的称为根的数据元素root,它在关系H下无前驱;
(2) 若D—{root}≠空集,则存在D-{root}的一个划分{D1,Dr} 且D1∩Dr=空集;
(3) 若D1≠空集,则D1中存在唯一元素x1, 4、集,则Dr中存在唯一的元素,xr, 5、
ClearBiTree(&T)
初始条件:二叉树T存在
操作结果:将二叉树T清空为空树
TreeBiEmpty(T)
初始条件:二叉树T存在
操作结果:若二叉树T为空树,则返回TRUE,否则返回FALSE
TreeBiDepth(T)
初始条件:二叉树T存在
操作结果:返回二叉树T的深度
Root(T)
初始条件:二叉树T存在
操作结果:返回T的根
Value(T,cur_e)
初始条件:二叉树T存在,cur_e是T中的某个结点
操作结果:返回cur_e的值
Assign(T, cur_e,value)
初始条件:二叉树T存在,cur_e是T中的某个结点
6、操作结果:结点cur_e赋值为value
Parent(T,cur_e)
初始条件:而擦树T存在,cur_e是T中的某个结点
操作结果:若cur_e是非根结点,则返回它的双亲,否则函数值为空
LeftChild(T,cur_e)
初始条件:二叉树T存在,cur_e是T中的某个结点
操作结果:若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回空
RightChild(&T,&p,i)
初始条件:二叉树T存在,cur_e是T中的某个结点
操作结果:若cur_e有右兄弟,则返回它的右兄弟,否则函数值为空
LeftSibling(T,e)
初始条件:二叉树T存在,e是T中 7、的某个结点
操作结果:返回e的左兄弟,若e是T的左孩子或无左兄弟,返回空
RightSibling(T,e)
初始条件:二叉树T存在,e是T中的某个结点
操作结果:返回e的右兄弟,若e是T的右孩子或无右兄弟,返回空
InsertChild(&T,&p,I,c)
初始条件:二叉树T存在,p指向T中某个结点,1<=i<=p所指结点的度+1,非空树c与T不相交
操作结果:插入c为T中p指结点的第i棵子树
DeleteChild(&T,&p,i)
初始条件:树T存在,p指向T中某个结点,1〈=i〈=p所值结点的度
操作结果:删除T中p所指结点的第i棵子树
PreOrderTrav 8、ereseTree(T,Visit())
初始条件:二叉树T存在,Visit是对界定操作的应用函数
操作结果:先序遍历T,对每个结点调用函数visit()一次且仅一次,一旦visit()失败,则操作失败
InOrderTravereseTree(T,Visit())
初始条件:二叉树T存在,Visit是对界定操作的应用函数
操作结果:中序遍历T,对每个结点调用函数visit()一次且仅一次,一旦visit()失败,则操作失败
PostOrderTravereseTree(T,Visit())
初始条件:二叉树T存在,Visit是对界定操作的应用函数
操作结果:后序遍历T,对每个 9、结点调用函数visit()一次且仅一次,一旦visit()失败,则操作失败
}ADT Tree
堆栈
ADT Stack{
数据对象:D={∈ElemType,i=1,2,…,n,n>=0}
数据关系:R1={∈D,i=2,…,n}
基本操作:
InitStack(&S)
操作结果:构造一个空栈S
DestroyStack(&S)
初始条件:栈S已存在
操作结果:栈S被销毁
ClearStack(&S)
初始条件:栈S已存在
操作结果:栈S清为空栈
StackEmpty(S)
初始条件:栈S已存在
操作结果:若S为空栈,则返回TRUE,否则FALSE
10、
StackLength(S)
初始条件:栈S已存在
操作结果:返回S元素的个数,即栈的长度
GeTop(S,&e)
初始条件:栈S已存在且非空
操作结果:用e返回S的栈顶元素
Push(&S,e)
初始条件:栈S已存在
操作结果:插入元素e为新的栈顶元素
Pop(&S,&e)
初始条件:栈S已存在且非空
操作结果:删除S的栈顶元素,并返回e
StackTraverse(S,visit())
初始条件:栈S已存在且非空
操作结果:从栈底到栈顶依次对S的每个元素调用函数visit(),一旦visit()失败,则操作失败
}ADT Stack
算法的基本思想
11、以(A+B)*(C—D/E)这样一个表达式为列求它的后缀表达式
按照优先级加上括号,得到:(A+B)*(C-(D/E))
然后从最外层括号开始,依次转化成二叉树
1、根是* ,左子树(A+B),右子树(C—(D/E))
2、右子树的根- ,右子树的左子树C,右子树的右子树(D/E)
3、(A+B)的根+,左子树A ,右子树B
4、(D/E)的根/ ,左子树D,右子树E
*
+
-
A
/
B
C
D
E
可以画出表达式对应的2叉树,操作数作为叶子节点,操作符作为非叶子节点,如图所示。
再逆序遍历二叉树可得逆波 12、兰表达式为:AB+CDE/-*
利用堆栈的方法计算后缀表达式的值
程序的流程
程序由三个模块组成:
(1)输入模块:在主函数中输入中缀表达式
(2)转换模块:将中缀表达式转换为后缀表达式,并打印
(3)计算模块:生成的后缀表达式用于计算,打印最后结果
三、详细设计
物理数据类型
二叉树
#define Max_TREE_SIZE 100
Typedef TElemType SqBiTree[MAX_TREE_SIZE];
SqBiTree bt;
堆栈
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
# 13、define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OVERFLOW -2
typedef float SElemtype;
typedef int Status;
算法的具体步骤
//基本操作的函数原型
//二叉树的存储结构表示
Typedef struct BiTNode{
TElemType data;
Srtuct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//基本操作的函数原型说明
Status CreatBiTree(B 14、iTree &T)
//按先序次序插入二叉树中结点的值(一个字符)
//构造二叉链表表示二叉树T
Status PreOrderTraverse(BiTreeT,Status (* Visit)(TELemType e))
//采用二叉链表的存储结构,Visit是对结点操作的应用函数
//先序遍历二叉树,对每个结点调用且仅调用一次Visit函数
//一旦Visit函数失败则操作失败
Status InOrderTraverse(BiTreeT,Status (* Visit)(TELemType e))
//采用二叉链表的存储结构,Visit是对结点操作的应用函数
//中序遍 15、历二叉树,对每个结点调用且仅调用一次Visit函数
//一旦Visit函数失败则操作失败
Status PostOrderTraverse(BiTreeT,Status (* Visit)(TELemType e))
//采用二叉链表的存储结构,Visit是对结点操作的应用函数
//后序遍历二叉树,对每个结点调用且仅调用一次Visit函数
//一旦Visit函数失败则操作失败
//堆栈的存储结构表示
typedef struct
{
SElemtype * base;
SElemtype * top;
int stacksize;
} SqStack;
St 16、atus InitStack(SqStack &S)
{
S。base = (SElemtype *)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
if (! S。base) exit(OVERFLOW);
S.top = S。base;
S。stacksize = STACK_INIT_SIZE;
return OK;
}
int StackLength(SqStack S)
{
//获得堆栈元素的个数
//填空
return S。top-S.base;
}
Status Push(SqS 17、tack &S, SElemtype e)
{
//入栈
//填空
S.top++;
*(S。top)=e;
return true;
}
Status Pop(SqStack &S, SElemtype &e)
{
//出栈
//填空
if(S.top
©2010-2025 宁波自信网络信息技术有限公司 版权所有
客服电话:4009-655-100 投诉/维权电话:18658249818