基于二叉树结构的表达式求值算法

实验报告

课程名称: 程序设计与数据结构 指导老师: ljq 成绩: 实验名称:基于二叉树结构的表达式求值算法 实验类型: 上机 同组学生姓名:

一、实验目的和要求(必填)

三、代码缺陷及修正记录

五、讨论、心得

二、实验内容和代码(必填) 四、实验结果与分析(必填)

一、实验目的和要求

1. 掌握编程工具的使用

2. 掌握二叉树数据结构在计算机上的实现

3. 掌握通过计算机编程解决问题的基本方法

二、实验内容和代码

1.实验内容:

● 编程实现基于二叉树结构的表达式求值算法

● 表达式包含加减乘除四则运算以及至少一层括弧运算

● 首先将输入的原表达式转换成二叉树结构,然后采用二叉树的后序递归遍历

方法求得表达式的值

● 将所有实验内容合并到一个工程,增加交互操作和循环处理(持续)

2.代码

1.头文件expnbitree .h

1 2 3 4 5 6 7 8 9

10

11

12

13

14

15

16

17

18

19

20

21

22 #include

#include

#include

#define EXP_LEN 100 //定义表达式的最大长度

#define DATA_LEN 20 //定义每个操作数的最大长度

typedef struct BiTNode

{

int dflag; //标志域,值为1,data[]存放操作运算符;值为0,data[]存放操作数char data[DATA_LEN + 1]; //数据域,存放:操作运算符或操作数

struct BiTNode *lchild, *rchild; //分别指向结点的左、右子树

}BiTNode, *BiTree; //定义二叉树结点及二叉树类型指针

int CreateBiTree(BiTree &bt, char *p, int len);

//创建二叉树,并用bt返回树的根地址,p为表达式的首地址,l为表达式的长度

int Calculate(BiTree bt, double &rst);

//计算表达式的值,bt为据表达式创建的二叉树,用rst返回表达式的值

int PreOrderTraverse(BiTree bt);//先序遍历二叉树bt,输出先序遍历序列

int InOrderTraverse(BiTree bt); //中序遍历二叉树bt,输出中序遍历序列

int PostOrderTraverse(BiTree bt); //后序遍历二叉树bt,输出后序遍历序列

int DestroyBiTree(BiTree &bt); //销毁二叉树

//二叉树结构的表达式求解算法入口

2.源文件expntree.c

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37 {

i = 0;

printf("请输入合法的表达式:\n");

gets_s(expn);

for (i = 0, len = 0; expn[i] != '\0'; i++) //去掉表达式中的空格,并计算表达式的长度if (expn[i] != ' ')

expn[len++] = expn[i];

expn[len] = '\0';

printf("正在构建二叉树……\n");

if (CreateBiTree(bt, expn, len))

printf("二叉树构建成功!\n");

else

{ //销毁未成功建立的二叉树,释放动态申请的内存

printf("二叉树构建失败!\n");

printf("将销毁二叉树…………");

if (DestroyBiTree(bt))

printf("二叉树销毁成功!\n");

else {

printf("二叉树销毁失败!\n");

exit(0);

}

continue;

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59 }

printf("输出表达式的先序遍历序列……:\n"); PreOrderTraverse(bt);

printf("\n");

printf("输出表达式的中序遍历序列……:\n"); InOrderTraverse(bt);

printf("\n");

printf("输出表达式的后序遍历序列……:\n"); PostOrderTraverse(bt);

printf("\n");

printf("计算表达式的值……:\n");

if (Calculate(bt, rst))

printf("%g\n", rst);

else

printf("计算表达式的值失败!\n");

printf("即将销毁二叉树…………");

if (DestroyBiTree(bt))

printf("二叉树销毁成功!\n");

else {

printf("二叉树销毁失败!\n");

exit(0);

}

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

printf("如果要继续计算下一个表达式,请输入1,否则,返回上一级:\n ");

scanf_s("%d", &n);

getchar();

} while (n==1);

}

//创建二叉树

int CreateBiTree(BiTree &bt, char *p, int len)

{

int i = 0, lnum = 0, rpst1 = -1, rpst2 = -1, pn = 0;

//lnum记录"("的未成对个数;

//rpst1/rpst2记录表达式中优先级最低的("*"、"/")/("+"、"-")的位置;

//pn记录操作数中"."的个数,以判断输入操作数是否合法

if (len == 0)

return 1;

if (!(bt = (BiTree)malloc(sizeof(BiTNode)))) {

printf("内存申请失败\n");

return 0;

}

else

{

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99 100 101 102 103 //初始化

bt->lchild = bt->rchild = NULL;

memset(bt->data, '\0', sizeof(bt->data));//memset是计算机中C/C++语言函数——memset(void

*s,int ch,size_t n); //将s所指向的某一块内存中的后n个字节的内容全部设置为ch指定的ASCII值,

//第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始

化工作,其返回值为s。bt->dflag = 1;

//默认bt为叶子节点(即,存放操作数)

//合法性检查

if (*p == '+' || *p == '*' || *p == '/' || *p == '.' || *p == ')') //表达式首不合法;

{

printf("表达式输入错误!\n");

return 0;

}

if (!(*(p + len - 1) == ')' || *(p + len - 1) >= '0'&&*(p + len - 1) <= '9')) //不为右

括弧或数字,则表达式尾不合法; {

printf("表达式输入错误!\n");

return 0;

}

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 if (len == 1) //此时只有表达式为数字,表达式才合法

if (*p<'0' || *p>'9') {

printf("表达式输入错误!\n");

return 0;

}

else {

bt->data[0] = *p;

return 1;

}

else if (len == 2) //此时只有表达式为正数或负数,表达式才合法if ((*p == '-' || *p >= '0'&&*p <= '9') && *(p + 1) >= '0'&&*(p + 1) <= '9') {

bt->data[0] = *p; bt->data[1] = *(p + 1);

return 1;

}

else {

printf("表达式输入错误!\n");

return 0;

}

//表达式合法,开始创建二叉树

else

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 {

if (*p == '(')

lnum++;

for (i = 1; i < len; i++)

{

//合法性检查

if (*(p + i) == '.')

{

if (!(*(p + i - 1) >= '0'&&*(p + i - 1) <= '9'))

{

printf("表达式输入错误!\n");

return 0;

}

}

else if (*(p + i) == '*' || *(p + i) == '/')

{

if (!(*(p + i - 1) >= '0'&&*(p + i - 1) <= '9' || *(p + i - 1) == ')'))

{

printf("表达式输入错误!\n");

return 0;

}

if (lnum == 0) rpst1 = i;

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 }

else if (*(p + i) == '(')

{

if (*(p + i - 1) == '+' || *(p + i - 1) == '-' || *(p + i - 1) == '*' || *(p

+ i - 1) == '/' || *(p + i - 1) == '(')

lnum++;

else {

printf("表达式输入错误!\n");

return 0;

}

}

else if (*(p + i) == ')')

{

if (*(p + i - 1) == ')' || *(p + i - 1) >= '0'&&*(p + i - 1) <= '9') lnum--;

else {

printf("表达式输入错误!\n");

return 0;

}

if (lnum < 0) {

printf("表达式输入错误!\n");

return 0;

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

}

}

else if (*(p + i) == '+' || *(p + i) == '-')

{

if (*(p + i) == '+'&&!(*(p + i - 1) >= '0'&&*(p + i - 1) <= '9' || *(p + i - 1) == ')'))

{

printf("表达式输入错误!\n");

return 0;

}

else if (*(p + i) == '-'&&!(*(p + i - 1) >= '0'&&*(p + i - 1) <= '9' ||

*(p + i - 1) == ')' || *(p + i - 1) == '('))

{

printf("表达式输入错误!\n");

return 0;

}

if (lnum == 0)

rpst2 = i;

}

}

if (lnum != 0) {

printf("表达式输入错误!\n");

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213

return 0;

}

//"("、")"未能完全配对,表达式输入不合法

if (rpst2 > -1)//+ -

{

bt->dflag = 0; //data[]存放操作数

bt->data[0] = *(p + rpst2);

if (CreateBiTree(bt->lchild, p, rpst2))

if (CreateBiTree(bt->rchild, p + rpst2 + 1, len - rpst2 - 1))

return 1;

return 0;

}

if (rpst1 < 0)//此时表明表达式或者是一个数字,或是表达式整体被一对括弧括起来{

if (*p == '(') //此时表达式整体被一对括弧括起来

if (CreateBiTree(bt, p + 1, len - 2))

return 1;

else return 0;

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 {

if (*(p + 1) != '(') //此时表达式一定是一个数字

{

for (i = 0; i < len; i++)

{

if (*(p + i) == '.')pn++;

if (pn > 1) {

printf("表达式输入错误!\n");

return 0;

}

bt->data[i] = *(p + i);

}

return 1;

}

else//此时表达式首一定是操作符"-",其余部分被一对括弧括起来{

bt->dflag = 0; bt->data[0] = '-';

if (CreateBiTree(bt->rchild, p + 2, len - 3))

return 1;

else return 0;

}

237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257

}

else//此时表明表达式为几个因子想成或相除而组成的

{

bt->dflag = 0; bt->data[0] = *(p + rpst1);

if (CreateBiTree(bt->lchild, p, rpst1))

if (CreateBiTree(bt->rchild, p + rpst1 + 1, len - rpst1 - 1))

return 1;

return 0;

}

}

}

}

//计算表达式

int Calculate(BiTree bt, double &rst)

{

double l = 0, r = 0;//l、r分别存放左右子树所代表的字表达式的值

if (!bt) {

rst = 0;

258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279

return 1;

}

if (bt->dflag == 1) {

rst = atof(bt->data);//atof(),是C语言标准库中的一个字符串处理函数,

//功能是把字符串转换成浮点数,

//所使用的头文件为。该函数名是“ascii to floating point numbers”的缩写。

//语法格式为:double atof(const char *nptr)。

return 1;

}

else

{

if (Calculate(bt->lchild, l))//后序

if (Calculate(bt->rchild, r))

{

switch (bt->data[0])

{

case'+': rst = l + r; break;

case'-': rst = l - r; break;

case'*': rst = l*r; break;

case'/': if (r == 0) {

printf("除数为0 !\n");

return 0;

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301

}

else {

rst = l / r;

break;

}

default: return 0;

}

//printf("%g%c%g=%g\n",l,bt->data[0],r,rst);//输出运算过程

return 1;

}

return 0;

}

}

//先序遍历二叉树

int PreOrderTraverse(BiTree bt)

{

if (bt)

{

printf("%s ", bt->data);

if (PreOrderTraverse(bt->lchild))

if (PreOrderTraverse(bt->rchild))

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323

return 1;

return 0;

}

return 1;

}

//中序遍历二叉树

int InOrderTraverse(BiTree bt)

{

if (bt)

{

if (InOrderTraverse(bt->lchild))

{

printf("%s ", bt->data);

if (InOrderTraverse(bt->rchild))

return 1;

return 0;

}

return 0;

}

return 1;

}

//后序遍历二叉树

324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 int PostOrderTraverse(BiTree bt)

{

if (bt)

{

if (PostOrderTraverse(bt->lchild))

if (PostOrderTraverse(bt->rchild))

{

printf("%s ", bt->data);

return 1;

}

else return 0;

}

return 1;

}

//销毁二叉树

int DestroyBiTree(BiTree &bt)

{

if (bt)

{

if (DestroyBiTree(bt->lchild))

if (DestroyBiTree(bt->rchild))

{

三、代码缺陷及修正记录

四、实验结果与分析

二叉树结构的表达式求值算法

(1.09*(21-6)/4.5-9.8)+(44-9.8*2)-(5-(4+9)/2)

1)从第一次范例表达式测试结果来看,本程序能够实现简单的四则运算和至少一层

表达式求值算法实现

湖南人文科技学院计算机科学技术系 课程设计说明书 课程名称:数据结构 课程代码:408024 题目: 表达式求值 年级/专业/班:08级计算机科学与技术二班 学生姓名: 黄胜李业芝黄自强 黄沅涛姚洋 学号:08408210 08408211 08408212

08408213 08408215 指导教师: 袁辉勇 开题时间: 2009 年12 月21 日 完成时间: 2010 年 1 月 1 日

目录 摘要 (1) 一、引言 (3) 二、设计目的与任务 (3) 1、课程设计目的 (3) 2、课程设计的任务 (4) 三、设计方案 (4) 1、需求分析 (4) 2、概要设计 (4) 3、详细设计 (6) 4、程序清单 (13) 四、调试分析与体会 (17) 五、运行结果 (18) 六、结论 (20) 七、致谢 (21) 八、参考文献 (21)

摘要 在高级语言环境中算术表达上的结果是通过语言环境预设的算法的思想计算出来的,然而高级语言初学者并不了解表达式的计算过程和方法。本文采用算符优先分析和堆栈的方法给出了算术表达式的计算过程。 所以本次课程设计的程序是在Windows系统上为用户解决包括加、减、乘、除以及括号在内的四则混合运算。用户可通过键盘输入四则运算,经过程序运行之后,可以判断出用户所输入的表达式是否正确。如果正确,就给出表达式的值;如果不正确,就提示输入有误。 关键词:四则混合运算;高级语言;栈 Abstract The arithmetic expression result is the algorithm thought which supposes in advance through the language environment calculatesin the higher order language environment,however the higher order language beginner does not understand the expression the computationprocess and the method. This article used the operator first to analyze and the storehouse method has given the arithmetic expression computa-tion process. Therefore, the procedure in this curriculum design is the solution for users on Windows systems, including add, subtract, multiply, divide and brackets, including four hybrid operation. Users can enter via the keyboard 4 operation, after a program is running, you can determine the user entered expression is correct. If correct, it gives the value of the expression; if not correct, it prompted an error.

数据结构表达式求值实验报告

竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告 篇一:数据结构实验二——算术表达式求值实验报告 《数据结构与数据库》 实验报告 实验题目算术表达式求值 学院:化学与材料科学学院 专业班级:09级材料科学与工程系pb0920603 姓学 邮名:李维谷号:pb09206285箱: liwg@https://www.360docs.net/doc/2c17122383.html,指导教师:贾伯琪 实验时间:20XX年10月10日 一、需要分析 问题描述: 表达式计算是实现程序设计语言的基本问题之一,它的实现是栈的应用的一个典型例子。设计一个程序,演示通过将数学表达式字符串转化为后缀表达式,并通过后缀表达式结合栈的应用实现对算术表达式进行四则混合运算。

问题分析: 在计算机中,算术表达式由常量、变量、运算符和括号组成。由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。因而在程序设计时,借助栈实现。 设置运算符栈(字符型)和运算数栈(浮点型)辅助分析算符优先关系。在读入表达式的字符序列的同时完成运算符和运算数的识别处理,然后进行运算数的数值转换在进行四则运算。 在运算之后输出正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。 算法规定: 输入形式:一个(:数据结构表达式求值实验报告)算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。为使实验更完善,允许操作数为实数,操作符为(、)、.(表示小数点)、+、-、*、/、^(表示乘方),用#表示结束。 输出形式:演示表达式运算的中间结果和整个表达式的最终结果,以浮点型输出。 程序功能:对实数内的加减乘除乘方运算能正确的运算出结果,并能正确对错误输入和无定义的运算报错,能连续测试多组数据。 测试数据:正确输入:12*(3.6/3+4^2-1)#

全国计算机等级考试二级公共基础之树与二叉树1

全国计算机等级考试二级公共基础之树与二叉树 1.6 树与二叉树 1.6.1 树的基本概念 树是一种简单的非线性结构。在树这种结构中,所有元素之间的关系具有明显的层次关系。用图形表示树这种数据结构时,就象自然界中的倒长的树,这种结构就用“树”来命名。如图: 在树结构中,每个结点只有一个前件,称为父结点,没有前件的结点只有一个,称为树的根结点,简称为树的根(如R)。 在树结构中,每一个结点可以有多个后件,它们都称为该结点的子结点。没有后件的结点称为叶子结点(如W,Z,A ,L,B,N,O,T,H,X)。 在树结构中,一个结点拥有的后件个数称为结点的度(如R的度为4,KPQDEC 结点度均为2)。 树的结点是层次结构,一般按如下原则分层:根结点在第1层;同一个层所有结点的所有子结点都在下一层。树的最大层次称为树的深度。如上图中的树深度为4。R结点有4棵子树,KPQDEC结占各有两棵子树;叶子没有子树。 在计算机中,可以用树结构表示算术运算。在算术运算中,一个运算符可以有若干个运算对象。如取正(+)与取负(-)运算符只有一个运算对象,称为单目运算符;加(+)、减(-)、乘(*)、除(/)、乘幂(**)有两个运算对象,称为双目运算符;三元函数f(x,y,z)为 f函数运算符,有三个运算对象,称为三目运算符。多元函数有多个运算对象称多目运算符。 用树表示算术表达式原则是: (1)表达式中的每一个运算符在树中对应一个结点,称为运算符结点

(2)运算符的每一个运算对象在树中为该运算结点的子树(在树中的顺序从 左到右) (3)运算对象中的单变量均为叶子结点 根据上面原则,可将表达式:a*(b+c/d)+c*h-g*f表示如下的树。 树在计算机中通常用多重链表表示,多重链表的每个结点描述了树中对应结点的信息,每个结点中的链域(指针域)个数随树中该结点的度而定。 1.6.2 二叉树及其基本性质 1. 什么是二叉树 二叉树是很有用的非线性结构。它与树结构很相似,树结构的所有术语都可用到二叉树这种结构上。 二叉树具有以下两个特点: (1)非空两叉树只有一个根结点 (2)每个结点最多有两棵子树,且分别称该结点的左子树与右子树。 也就是说,在二叉树中,每一个结点的度最大为2,而且所有子树也均为二叉树。二叉树中的每一个结点可以有左子树没有右子树,也可以有右子树没有左子树,甚至左右子树都没有。

数据结构实验二叉树

实验六:二叉树及其应用 一、实验目的 树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。 二、问题描述 首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。 如算术表达式:a+b*(c-d)-e/f 三、实验要求 如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算统计叶子结点的个数。求二叉树的深度。十进制的四则运算的计算器可以接收用户来自键盘的输入。由输入的表达式字符串动态生成算术表达式所对应的二叉树。自动完成求值运算和输出结果。四、实验环境 PC微机 DOS操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、根据二叉树的各种存储结构建立二叉树; 2、设计求叶子结点个数算法和树的深度算法; 3、根据表达式建立相应的二叉树,生成表达式树的模块; 4、根据表达式树,求出表达式值,生成求值模块; 5、程序运行效果,测试数据分析算法。 六、测试数据 1、输入数据:*(+)3 正确结果: 2、输入数据:(1+2)*3+(5+6*7);

正确输出:56 七、表达式求值 由于表达式求值算法较为复杂,所以单独列出来加以分析: 1、主要思路:由于操作数是任意的实数,所以必须将原始的中缀表达式中的操作数、操作符以及括号分解出来,并以字符串的形式保存;然后再将其转换为后缀表达式的顺序,后缀表达式可以很容易地利用堆栈计算出表达式的值。 例如有如下的中缀表达式: a+b-c 转换成后缀表达式为: ab+c- 然后分别按从左到右放入栈中,如果碰到操作符就从栈中弹出两个操作数进行运算,最后再将运算结果放入栈中,依次进行直到表达式结束。如上述的后缀表达式先将a 和b 放入栈中,然后碰到操作符“+”,则从栈中弹出a 和b 进行a+b 的运算,并将其结果d(假设为d)放入栈中,然后再将c 放入栈中,最后是操作符“-”,所以再弹出d和c 进行d-c 运算,并将其结果再次放入栈中,此时表达式结束,则栈中的元素值就是该表达式最后的运算结果。当然将原始的中缀表达式转换为后缀表达式比较关键,要同时考虑操作符的优先级以及对有括号的情况下的处理,相关内容会在算法具体实现中详细讨论。 2、求值过程 一、将原始的中缀表达式中的操作数、操作符以及括号按顺序分解出来,并以字符串的 形式保存。 二、将分解的中缀表达式转换为后缀表达式的形式,即调整各项字符串的顺序,并将括 号处理掉。 三、计算后缀表达式的值。 3、中缀表达式分解 DivideExpressionToItem()函数。分解出原始中缀表达式中的操作数、操作符以及括号,保存在队列中,以本实验中的数据为例,分解完成后队列中的保存顺序如下图所示:

数据结构课程设计_表达式求值问题

实验表达式求值问题 1.问题描述 表达式是数据运算的基本形式。人们的书写习惯是中缀式,如:11+22*(7-4)/3.中缀式的计算按运算符的优先级及括号优先的原则,相同级别从左到右进行计算。表达式还有后缀表达式(如:11 22 7 4 - * 3 / +)和前缀表达式(+ 11 / * 22 - 7 4 3)。后缀表达式 和前缀表达式中没有括号,给计算带来方便。如后缀表达式计算时按运算符出现的先后进行计算。本设计的主要任务是进行表达式形式的转换及不同形式的表达式计算。 2.数据结构设计 (1)顺序栈类定义:首先应在类中定义成员函数,以此来完成顺序栈的相关操作,如下: class SqStack { private: T *base; //栈底指针 int top; //栈顶 int stacksize; //栈容量public: SqStack(int m); //构建函数 ~SqStack(){delete [] base;top=0;stacksize=0;} //析构函数 void Push(T x); //入栈 T Pop(); //出栈 T GetTop(); //获取栈顶元素

int StackEmpty(); //测栈空 void ClearStack(); //清空栈 void StackTop(); //返回栈顶指针 void StackTranverse(); //显示栈中元素 }; (2)顺序栈类实现:对顺序栈进行初始化,初始化的首要操作就是创建一个空顺序栈。 Step1:申请一组连续的存空间为顺序栈使用: base=new T[m]; i f(base==NULL) { cout<<"栈创建失败,退出!"<

数据结构实验二——算术表达式求值实验报告

《数据结构与数据库》 实验报告 实验题目 算术表达式求值 学院:化学与材料科学学院 专业班级:09级材料科学与工程系PB0920603 姓名:李维谷 学号:PB09206285 邮箱:liwg@https://www.360docs.net/doc/2c17122383.html, 指导教师:贾伯琪 实验时间:2010年10月10日 一、需要分析 问题描述:

表达式计算是实现程序设计语言的基本问题之一,它的实现是栈的应用的一个典型例子。设计一个程序,演示通过将数学表达式字符串转化为后缀表达式,并通过后缀表达式结合栈的应用实现对算术表达式进行四则混合运算。 问题分析: 在计算机中,算术表达式由常量、变量、运算符和括号组成。由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。因而在程序设计时,借助栈实现。 设置运算符栈(字符型)和运算数栈(浮点型)辅助分析算符优先关系。在读入表达式的字符序列的同时完成运算符和运算数的识别处理,然后进行运算数的数值转换在进行四则运算。 在运算之后输出正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。 算法规定: 输入形式:一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。为使实验更完善,允许操作数为实数,操作符为(、)、.(表示小数点)、+、-、*、/、^(表示乘方),用#表示结束。 输出形式:演示表达式运算的中间结果和整个表达式的最终结果,以浮点型输出。 程序功能:对实数内的加减乘除乘方运算能正确的运算出结果,并能正确对错误输入和无定义的运算报错,能连续测试多组数据。 测试数据:正确输入:12*(3.6/3+4^2-1)# 输出结果:194.4

用栈和二叉树实现中缀表达式转后缀表达式构建计算机并求值实验报告

实验报告 姓名:黄雄镖学号:13331093 院系专业:软件学院2013级教务4班 完成日期:2014 年10 月20 日 实验题目:实现一个较为通用的计算器 需求分析: 实现一个包含加减乘除运算的较为通用的计算器,操作数可能是负数,并且可能是多位数。运算式中可以有括号和多余空格。计算器对负号不敏感, 形如1+-1或者1+(-1)都是可以接受的。 概要设计 思路: 将表达式的中缀表达式转换成后缀表达式,然后利用一个栈或者建立二叉树对后缀表达式进行求值。 由于多位数在转为后缀表达式时会分不清, 故在每个数和运算符后面加上一个空格作为区别 在主程序中调用用栈求值的计算器类和用二叉树计算的计算器类, 输出算式的结果 13331093_03.h里存放用栈求值的计算器类 13331093_03_tree.h里存放用二叉树计算的计算器类 13331093_03.h的类里主要包括: 获得算术表达式的函数getexpression(string expression), expression为所要计算的算术表达式计算函数calculate(string num2, string num1, string op), 输入为两个数(字符串形式)和一个操作符, 返回值为计算结果(字符串形式) 返回中缀表达式函数ShowMiddleExpression(), 返回的中缀表达式为字符串形式 RidSpace(string origin)用于去除输入中多余的空格, 输入为要除去空格的算术表达式, 返回去掉空格的算术表达式

MidToLast(string str)中缀表达式转后缀表达式 获得后缀表达式函数GetLastExpression(), 返回的后缀表达式为字符串形式 用栈执行计算后缀表达式函数exe(), 返回计算结果为字符串形式 13331093_03_tree.h类里主要包括: 获得算术表达式的函数getexpression(string expression), expression为所要计算的算术表达式计算函数calculate(string num2, string num1, string op), 输入为两个数(字符串形式)和一个操作符, 返回值为计算结果(字符串形式) 返回中缀表达式函数ShowMiddleExpression(), 返回的中缀表达式为字符串形式 RidSpace(string origin)用于去除输入中多余的空格, 输入为要除去空格的算术表达式, 返回去掉空格的算术表达式 MidToLast(string str)中缀表达式转后缀表达式 获得后缀表达式函数GetLastExpression(), 返回的后缀表达式为字符串形式 生成一颗二叉树的函数makeTree(TNode *&p) 后序遍历二叉树并计算的函数PostOrder(TNode *p), 返回计算结果为字符串形式 a.调试过程遇到的问题与解决方案: 遇到的问题:调试过程中出现程序崩溃的现象, 后来debug发现是没有考虑到执行运算过程中出现的-()的情况 原因:没有考虑-()的情况, 导致栈为空的时候还弹出元素 解决方案:特殊处理这种情况 b.时间和空间复杂度:

表达式用二叉树表示(1)

数据结构程序报告(3) 2011.3.29

2. 需求分析: (1)功能:表达式可以用二叉树表示,对于简单的四则运算,请实现以下功能【1】对于任意给出的前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号),能够在计算机内部构造出一棵表达式二叉树,并且图示出来(图形的形式)。 【2】对于构造好的内部表达式二叉树,按照用户的要求输出相应的前缀表达式(不带括号)、中缀表达式(可以带括号,但不允许冗余括)或后缀表达式(不带括号)。 提示:所谓中缀表达式中的冗余括号,就是去掉括号后不影响表达式的计算顺序。例如:“(c+b)+a”中的括号是冗余的,可以表示成不冗余的“c+b+a”。 (2)输入输出要求:请输入字符串表达式: 树形二叉树(图形显示) 中缀表达式为: 前缀表达式为: 后缀表达式为: 3.概要设计:(算法) 分成两部分完成: 【1】前缀、中缀、后缀表达式->二叉树表达式 前缀表达式->二叉树表达式:(a)碰到操作数则把其值赋给相应的新申请的二叉树结点,地址压栈;(b)碰到操作符则把其值赋给相应的新申请的二叉树,并从栈中弹出两个地址,分别作为其右指针和左指针,然后再把其地址压栈,最后一个地址即为二叉树的根结点地址。 中缀表达式->二叉树表达式:把中缀表达式转换成后缀表达式,然后再建立二

叉树。 后缀表达式->二叉树表达式:(a)碰到操作数则把其值赋给相应的新申请的二叉树结点,若栈为空则地址压栈,若非空则取栈顶元素,若栈顶元素的左孩子为空则当前结点设为其左孩子,左孩子为满则设为其右孩子再压栈;(b)碰到操作数则把其值赋给相应的新申请的二叉树结点,取栈顶元素,若栈顶元素的左孩子为空则设为其左孩子,左孩子为满则设为其右孩子开始那个元素地址为根结点地址,开始时用变量root保存。 【1】二叉树表达式->前缀、中缀、后缀表达式 二叉树表达式->前缀表达式:对二叉树表达式进行前序遍历。 二叉树表达式->中缀表达式:对二叉树表达式进行中序遍历,若结点操作符的优先级高于其左或右子树,在打印相应的子树之前先打印开括号,在打印相应的子树最后在打印一个闭括号。 二叉树表达式->后缀表达式:对二叉树表达式进行后序遍历。

算术表达式求值演示程序

数理学院 课程设计报告书 课程名称数据结构课程设计 设计题目算术表达式求值演示 专业班级 学号 姓名 指导教师

2014 年12 月

4.2.2 基本操作: InitStack(&S) 操作结果:构造一个空栈S。 GetTop(S) 初始条件:栈S 已存在。 操作结 果: 用P 返回S的栈顶元素。Push(&S 初始条 件:,ch) 栈S 已存在。 操作结 果:插入元素ch 为新的栈顶元素。 Pop(&S) 初始条件:栈S 已存在。 操作结 果:删除S 的栈顶元素。 In(ch) 操作结果:判断字符是否是运算符,运算符即返回1 Precede(c1, c2) 初始条件:c1,c2 为运算符。操作结果:判断运算符优先权,返回优先权高的。Operate(a,op,b) 初始条件:a,b 为整数,op为运算符。操作结果: a 与 b 进行运算,op 为运算符,返回其值。num(n) 操作结果:返回操作数的长度。EvalExpr() 初始条件:输入表达式合法。操作结果:返回表达式的最终结果。}ADT Stack 主程序的流程:

EvaluateExpression() 函数实现了对表达式求值的功能,main() 函数直接调用EvaluateExpression() 对输入的表达式求值输出。 4.2.3 函数的调用关系图

4.3 详细设计 4.3.1 ① . Precede(char c1,char c2)判断运算符优先权,返回优先权高的 算符间的优先关系 如下: 算法伪代码如下: char Precede(char c1,char c2) { static char array[49]={ >', '>', '<', '<', '<', '>', '>', >', '>', '<', '<', '<', '>', '>', >', '>', '>', '>', '<', '>', '>', >', '>', '>', '>', '<', '>', '>', <', '<', '<', '<', '<', '=', '!', >', '>', '>', '>', '!', '>', '>', <', '<', '<', '<', '<', '!', '='}; // 用一维数组存储 49 种情况 switch(c1) { /* i 为下面 array 的横标 */ case '+' : i=0;break; case '-' : i=1;break; case '*' : i=2;break;

第6章树和二叉树习题

第六章 树和二叉树 一、选择题 1.算术表达式a+b*(c+d/e )转为后缀表达式后为( B ) A .ab+cde/* B .abcde/+*+ C .abcde/*++ D .2. 设有一表示算术表达式的二叉树(见下图), 它所表示的算术表达式是( C ) A. A*B+C/(D*E)+(F-G) B. (A*B+C)/(D*E)+(F-G) C. (A*B+C)/(D*E+(F-G )) D. A*B+C/D*E+F-G 3. 设树T 的度为4,其中度为1,2,3和4的结点个数分别为4,2,1 ,1 则T 中的叶子数为( D ) A .5 B .6 C .7 D .8 4. 在下述结论中,正确的是( D ) ①只有一个结点的二叉树的度为0; ②二叉树的度为2; ③二叉树的左右子树可任意 交换; ④深度为K 的完全二叉树的结点个数小于或等于深度相同的满二叉树。 A .①②③ B .②③④ C .②④ D .①④ 5. 设森林F 对应的二叉树为B ,它有m 个结点,B 的根为p,p 的右子树结点个数为n,森林F 中第一棵树的结点个数是( A ) A .m-n B .m-n-1 C .n+1 D .条件不足,无法确定 6.若一棵二叉树具有10个度为2的结点,5个度为1的结点,则度为0的结点个数是( B ) A .9 B .11 C .15 D .不确定 7.设森林F 中有三棵树,第一,第二,第三棵树的结点个数分别为M1,M2和M3。与森林F 对应的二叉树根结点的右子树上的结点个数是( D )。 A .M1 B .M1+M2 C .M3 D .M2+M3 8.一棵完全二叉树上有1001个结点,其中叶子结点的个数是( E ) A . 250 B . 500 C .254 D .505 E .以上答案都不对 9. 有关二叉树下列说法正确的是( B ) A .二叉树的度为2 B .一棵二叉树的度可以小于2 C .二叉树中至少有一个结点的度为2 D .二叉树中任何一个结点的度都为2 10.二叉树的第I 层上最多含有结点数为( C ) A .2I B . 2I-1-1 C . 2I-1 D .2I -1 11. 一个具有1025个结点的二叉树的高h 为( C ) A .11 B .10 C .11至1025之间 D .10至1024之间 12.一棵二叉树高度为h,所有结点的度或为0,或为2,则这棵二叉树最少有( B )结点 A .2h B .2h-1 C .2h+1 D .h+1 13. 一棵树高为K 的完全二叉树至少有( C )个结点 A .2k –1 B. 2k-1 –1 C. 2k-1 D. 2 k 14.对二叉树的结点从1开始进行连续编号,要求每个结点的编号大于其左、右孩子的编号,同一结点的左右孩子中,其左孩子的编号小于其右孩子的编号,可采用( C )次序的遍历 实现编号。 A .先序 B. 中序 C. 后序 D. 从根开始按层次遍历 15.一棵二叉树的前序遍历序列为ABCDEFG ,它的中序遍历序列可能是( B )

算术表达式与二叉树课程设计

山西大学 课程设计任务书 设计题目算术表达式与二叉树 所属课程:数据结构 系别软件学院 专业软件工程 班级软工1408班 姓名霍志斌 指导教师李雪梅 设计任务下达日期 2015年 12 月15 日 设计时间2016年1月4日至 2016年1月8日

目录: 一、需求分析 二、概要设计 1、数据类型的声明: 2、表达式的抽象数据类型定义 3、整体设计 三、详细设计 1、二叉树的存储类型 2、顺序栈的存储类型 3、表达式的基本操作 4、主程序和其他伪码算法 5、函数的调用关系 四、设计和调试分析 五、测试 六、课程设计的心得和心得以及问题 一、需求分析【课程设计要求】 【问题的描述】 一个表达式和一棵二叉树之间,存在着自然的对应关系。写一个程序,实现基于二叉树表示的算术表达式Expression的操作。 【基本要求】 假设算术表达式Expression内可以含有变量(a-z),常量(0-9)和二元运算符(+,-,*,/,^(乘幂))。实现以下操作: (1)ReadExpr(E)――以字符序列的形式输入语法正确的前缀表达式并构造表达式E。 (2)WriteExpr(E)――用带括号的中缀表达式输出表达式E。

(3)Assign(V,c)――实现对变量V的赋值(V=c),变量的初值为0。 (4)Value(E)――对算术表达式E求值。 (5)CompoundExpr(p,E1,E2)――构造一个新的复合表达式(E1)p(E2)。【测试数据】 1)分别输入0;a;-91;+a*bc;+*5x2*8x;+++*3^*2^x2x6并输出。 2)每当输入一个表达式后,对其中的变量赋值,然后对表达式求值。 二、概要设计 1、数据类型的声明: 在这个课程设计中,采用了链表二叉树的存储结构,以及两个顺序栈的辅助存储结构 /*头文件以及存储结构*/ #include #include #include #include #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW 0 typedef int Status; 2、表达式的抽象数据类型定义 ADT Expression{ 数据对象D:D是具有数值的常量C和没有数值的变量V; 数据关系:R={<(V或者C)P(V或者C)>|V,C∈D, <(V或者C)P(V或者C)>表示由运算符P结合起来的表达式E} 基本操作: Status Input_Expr(&string,flag) 操作结果:以字符序列的形式输入语法正确的前缀表达式,保存到字符串string; 参数flag表示输出的提示信息是什么,输入成功返回OK,否则,返回ERROR。 void judge_value(&E,&string,i) 初始条件:树E存在,表达式的前缀字符串string存在; 操作结果:判断字符string[i],如果是'0'-'9'常量之间,二叉树结点E存为整 型;否则,存为字符型。 Status ReadExpr(&E,&exprstring) 初始条件:表达式的前缀形式字符串exprstring存在; 操作结果:以正确的前缀表示式exprstring并构造表达式E,构造成功,返回OK, 否则返回ERROR。 Status Pri_Compare(c1,c2)

后缀表达式求值的算法及代码

#include #include struct node // 栈结构声明 { int data; // 数据域 struct node *next; // 指针域 }; typedef struct node stacklist; // 链表类型 typedef stacklist *link; // 链表指针类型 link operand=NULL; // 操作数栈指针 link push(link stack,int value) // 进栈 { link newnode; // 新结点指针 newnode=new stacklist; // 分配新结点 if (!newnode) { printf("分配失败!"); return NULL; } newnode->data=value; // 创建结点的内容 newnode->next=stack; stack=newnode; // 新结点成为栈的开始return stack; } link pop(link stack,int *value) // 出栈 { link top; // 指向栈顶 if (stack !=NULL) { top=stack; // 指向栈顶 stack=stack->next; // 移动栈顶指针 *value=top->data; // 取数据 delete top; // 吸收结点 return stack; // 返回栈顶指针} else *value=-1; } int empty(link stack) // 判栈空 { if (stack!=NULL)

数据结构算术表达式求值实验报告

软件技术基础实验报告 实验名称:表达式计算器 系别:通信工程 年级: 班级: 学生学号: 学生姓名: 《数据结构》课程设计报告 题目简易计算表达式的演示 【题目要求】 要求:实现基本表达式计算的功能 输入:数学表达式,表达式由整数和“+”、“-”、“×”、“/”、“(”、“)”组成输出:表达式的值 基本操作:键入表达式,开始计算,计算过程和结果记录在文档中 难点:括号的处理、乘除的优先级高于加减

1.前言 在计算机中,算术表达式由常量、变量、运算符和括号组成。由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。因而在程序设计时,借助栈实现。 算法输入:一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。为简化,规定操作数只能为正整数,操作符为+、-*、/、=,用#表示结束。 算法输出:表达式运算结果。 算法要点:设置运算符栈和运算数栈辅助分析算符优先关系。在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,以及相应运算。 2.概要设计 2.1 数据结构设计 任何一个表达式都是由操作符,运算符和界限符组成的。我们分别用顺序栈来寄存表达式的操作数和运算符。栈是限定于紧仅在表尾进行插入或删除操作的线性表。顺序栈的存储结构是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top 指示栈顶元素在顺序栈中的位置,base 为栈底指针,在顺序栈中,它始终指向栈底,即top=base 可作为栈空的标记,每当插入新的栈顶元素时,指针top 增1,删除栈顶元素时,指针top 减1。 2.2 算法设计 为了实现算符优先算法。可以使用两个工作栈。一个称为OPTR ,用以寄存运算符,另一个称做OPND ,用以寄存操作数或运算结果。 1.首先置操作数栈为空栈,表达式起始符”#”为运算符栈的栈底元素; 2.依次读入表达式,若是操作符即进OPND 栈,若是运算符则和OPTR 栈的栈顶运算符比较优先权后作相应的操作,直至整个表达式求值完毕(即OPTR 栈的栈顶元素和当前读入的字符均为”#”)。 2.3 ADT 描述 ADT Stack{ 数据对象:D={ i a |i a ∈ElemSet,i=1,2,…,n, n ≧0} 数据对象:R1={< 1 ,-i i a a >| 1-i a ,D a i ∈,i=2,…,n}

算术表达式与二叉树

目录 一、系统开发的背景 (1) 二、系统分析与设计 (1) (一)系统功能要求 (1) (二)系统模块结构设计 (1) 三、系统的设计与实现 (3) (一)二叉树的遍历 (3) (二)算术表达式求值 (5) 四、系统测试 (9) (一)测试二叉树遍历函数 (9) (二)测试算术表达式求值函数 (10) 五、总结 (10) 六、附件(代码、部分图表) (10) (一)程序代码 (10) (二)实验截图 (15)

算术表达式与二叉树 一、系统开发的背景 为了方便进行基本的算术运算,减轻对数字较大的数操作时所带来的麻烦,及其在运算过程中错误的避免。因此设计算术表达式与二叉树的程序来解决此问题。 二、系统分析与设计 (一)系统功能要求 由于一个表达式和一棵二叉树之间,存在着自然的对应关系。遍写一个程序,实现基于二叉树表示的算术表达式的操作。算术表达式内可以含有变量(a~z)、常量(0~9)和二元运算符(+,-,*,/,^(乘幂))。 具体实现以下操作: 1以字符序列的形式输入语法正确的前缀表达式并构造表达式。 2用带括弧的中缀表达式输出表达式。 3实现对变量V的赋值(V=c),变量的初值为0。 4对算术表达式E求值。 (二)系统模块结构设计 通过对系统功能的分析,基于二叉树表示的算术表达式的功能 如图(1)所示。

图1:基于二叉树表示的算术表达式的功能图 通过上图的功能分析,把整个系统划分为主要的两大个模块: 1、将语法正确的前缀表达式用二叉树的遍历转换成相应的遍历序列,必要时可以求出此二叉树的结点数及其树的深度。该模块借助函数BiTree Create(BiTree T)创建二叉树,void Preorder(BiTree T) 先序遍历, void InOrder(BiTree T)中序遍历,void PostOrder(BiTree T)后序遍历,int Sumleaf(BiTree T)统计叶结点的数目,int Depth(BiTree T)二叉树的深度6个函数联合来实现; 2、计算中序遍历所得的算术表达式的值。其中先要将扫描得到的中缀表达式转换为后缀表达式,然后利用栈的初始化,进栈与取栈顶元素操作进行对后缀表达式进行计算。该模块借助函数void InitStack(SeqStack *S)初始化栈,int PushStack(SeqStack *S,char e)进栈,int GetTop(SeqStack

基于二叉树结构的表达式求值算法

实验报告 课程名称: 程序设计与数据结构 指导老师: ljq 成绩: 实验名称:基于二叉树结构的表达式求值算法 实验类型: 上机 同组学生姓名: 一、实验目的和要求(必填) 三、代码缺陷及修正记录 五、讨论、心得 二、实验内容和代码(必填) 四、实验结果与分析(必填) 一、实验目的和要求 1. 掌握编程工具的使用 2. 掌握二叉树数据结构在计算机上的实现 3. 掌握通过计算机编程解决问题的基本方法 二、实验内容和代码 1.实验内容: ● 编程实现基于二叉树结构的表达式求值算法 ● 表达式包含加减乘除四则运算以及至少一层括弧运算 ● 首先将输入的原表达式转换成二叉树结构,然后采用二叉树的后序递归遍历 方法求得表达式的值 ● 将所有实验内容合并到一个工程,增加交互操作和循环处理(持续) 2.代码 1.头文件expnbitree .h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include #include #include #define EXP_LEN 100 //定义表达式的最大长度 #define DATA_LEN 20 //定义每个操作数的最大长度 typedef struct BiTNode { int dflag; //标志域,值为1,data[]存放操作运算符;值为0,data[]存放操作数char data[DATA_LEN + 1]; //数据域,存放:操作运算符或操作数 struct BiTNode *lchild, *rchild; //分别指向结点的左、右子树 }BiTNode, *BiTree; //定义二叉树结点及二叉树类型指针 int CreateBiTree(BiTree &bt, char *p, int len); //创建二叉树,并用bt返回树的根地址,p为表达式的首地址,l为表达式的长度 int Calculate(BiTree bt, double &rst); //计算表达式的值,bt为据表达式创建的二叉树,用rst返回表达式的值 int PreOrderTraverse(BiTree bt);//先序遍历二叉树bt,输出先序遍历序列 int InOrderTraverse(BiTree bt); //中序遍历二叉树bt,输出中序遍历序列 int PostOrderTraverse(BiTree bt); //后序遍历二叉树bt,输出后序遍历序列 int DestroyBiTree(BiTree &bt); //销毁二叉树 //二叉树结构的表达式求解算法入口

表达式求值课程设计报告

表达式求值课程设计报告 表达式求值 《数据结构》 课程设计报告 题目: 栈的应用:表达式求值 (系): 信息科学与工程学院院 专业班级: 软件工程1102班学生姓名: 学号: 指导教师: 20 13 年 6 月 8 日至20 13 年 6 月 21 日 表达式求值 目录 目录 (2) 1 概述 (1) 1.1 课程设计目的 (1) 1.2 课程设计内容 (1) 2 系统需求分析 ...................................................... 1 2.1 系统目标 (1) 2.2 主体功能 (1) 2.3 开发环境 (1) 3 系统概要设计 .................................................... 2 3.1 系统的功能模块划分 (2)

3.2 系统流程图 (2) 4系统详细设计 ..................................................... 3 5 测试 ............................................................ 6 5.1 测试方案 (6) 5.2 测试结果 (6) 6 小结 ............................................................ 8 参考文献 .......................................................... 9 附录1 源程序清单 (10) 2 数据结构课程设计报告(2012) 表达式求值 1 概述 1.1 课程设计目的 1(要求学生达到熟练掌握C语言的基本知识和技能。 2(了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力。 3(提高程序设计和调试能力。学生通过上机实习,验证自己设计的算法的正确性。学会有效利用基本调试方法,迅速找出程序代码中的错误并且修改。 4(培养算法分析能力。分析所设计算法的时间复杂度和空间复杂度,进一步提 高程序设计水平。

c语言实现一.二叉树操作 二.用栈实现算术表达式求值 课设报告

目录 题目一.二叉树操作(1)二.算术表达式求 (1) 一、课程设计的目的 (1) 二、课程设计的内容和要求 (1) 三、题目一设计过程 (2) 四、题目二设计过程 (6) 五、设计总结 (17) 六、参考文献 (18)

题目一.二叉树操作(1)二.算术表达式求 一、课程设计的目的 本学期我们对《数据结构》这门课程进行了学习。这门课程是一门实践性非常强的课程,为了让大家更好地理解与运用所学知识,提高动手能力,我们进行了此次课程设计实习。这次课程设计不但要求学生掌握《数据结构》中的各方面知识,还要求学生具备一定的C语言基础和编程能力。 (1)题目一的目的: 1、掌握二叉树的概念和性质 2、掌握二叉树的存储结构 3、掌握二叉树的基本操作 (2)题目二的目的: 1、掌握栈的顺序存储结构和链式存储结构 2、掌握栈的先进后出的特点 3、掌握栈的基本运算 二、课程设计的内容和要求 (1)题目一的内容和要求: 1、编写已知二叉树的先序、中序序列,恢复此二叉树的程序 2、编写求二叉树深度的程序 (2)题目二的内容和要求: 1、算术表达式由操作数、运算符和界限符组成。操作数是正整数,运算符为 加减乘除,界限符有左右括号和表达式起始 2、将一个表达式的中缀形式转化为相应的后缀形式 3、依据后缀表达式计算表达式的值

三、题目一设计过程 1、题目分析 现已知一棵二叉树的先序遍历序列和中序遍历序列,依次从先序遍历序列中取结点,由先序序列确定根结点(就是第一个字母),每次取出一个结点就与中序遍历的序列进行比较,当相等的时候,中序遍历序列就被分成以该结点为根的二叉树子树,该结点左部分为左子树,右部分为右子树,直到取完先序列里的所有结点,则二叉树构造完毕(树用链式存储结构存储),用递归实现! 由建好的二叉树,先判断这棵树是否为空,若不为空则找数的左子树,统计它的高度,然后找树的右子树,统计它的高度,比较左子树和右子树的高度,然后返回其中大的那个值加一,则求出数的高度。这里用递归实现! 2、算法描述 main ( )(主函数) 先构造一颗二叉树,初始化为空,用来存储所构造的二叉树,并输入一棵树的先序序列和中序序列,并统计这个序列的长度。然后调用实现功能的函数。 void CreateBiTree(BiTree *T,char *pre,char *in,int len)(由先序序列和中序序列构造二叉树) 根据前序遍历的特点, 知前序序列(pre)的首个元素(pre[0])为根(root), 然后在中序序列(in)中查找此根(pre[0]), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为左子树, 后边的序列为右子树。设根前边有n个元素,则又有, 在前序序列中,紧跟着根(root)的n个元素序列(即pre[1...n]) 为左子树, 在后边的为右子树,而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为pre[1...n]), 中序序列为in[0...n-1], 分别为原序列的子串, 构造右子树同样。这里用递归实现! int Depth(BiTree T)(求树的深度) 当所给的参数T是NULL时,返回0。说明这个树只有一个叶子节点深度为0,当所给的参数不是NULL时,函数调用自己看看这个参数的左分支是不是NULL,

相关文档
最新文档