基于二叉树结构的表达式求值算法Word文档下载推荐.docx
《基于二叉树结构的表达式求值算法Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于二叉树结构的表达式求值算法Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
//计算表达式的值,bt为据表达式创建的二叉树,用rst返回表达式的值
intPreOrderTraverse(BiTreebt);
//先序遍历二叉树bt,输出先序遍历序列
intInOrderTraverse(BiTreebt);
//中序遍历二叉树bt,输出中序遍历序列
intPostOrderTraverse(BiTreebt);
//后序遍历二叉树bt,输出后序遍历序列
intDestroyBiTree(BiTree&
bt);
//销毁二叉树
//二叉树结构的表达式求解算法入口
voidexpnbitree();
2.源文件expntree.c
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
#include"
expnbitree.h"
//ExpnBiTree实现子程序入口
voidexpnbitree()
intn,len,i;
//n标志量,值为0,退出程序;
len存储表达式的长度;
i一般变量
charexpn[EXP_LEN+1];
//存放表达式
doublerst;
//存放表达式计算结果
BiTreebt=NULL;
//声明一个二叉树
gets_s(expn);
do
{
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]='
正在构建二叉树……\n"
if(CreateBiTree(bt,expn,len))
printf("
二叉树构建成功!
else
{//销毁未成功建立的二叉树,释放动态申请的内存
二叉树构建失败!
将销毁二叉树…………"
if(DestroyBiTree(bt))
printf("
二叉树销毁成功!
else{
二叉树销毁失败!
exit(0);
}
continue;
}
输出表达式的先序遍历序列……:
PreOrderTraverse(bt);
输出表达式的中序遍历序列……:
InOrderTraverse(bt);
输出表达式的后序遍历序列……:
PostOrderTraverse(bt);
计算表达式的值……:
if(Calculate(bt,rst))
%g\n"
rst);
计算表达式的值失败!
即将销毁二叉树…………"
if(DestroyBiTree(bt))
else{
exit(0);
如果要继续计算下一个表达式,请输入1,否则,返回上一级:
\n"
scanf_s("
%d"
&
n);
getchar();
}while(n==1);
}
//创建二叉树
bt,char*p,intlen)
inti=0,lnum=0,rpst1=-1,rpst2=-1,pn=0;
//lnum记录"
("
的未成对个数;
//rpst1/rpst2记录表达式中优先级最低的("
*"
、"
/"
)/("
+"
-"
)的位置;
//pn记录操作数中"
."
的个数,以判断输入操作数是否合法
if(len==0)
return1;
if(!
(bt=(BiTree)malloc(sizeof(BiTNode)))){
内存申请失败\n"
return0;
}
else
//初始化
bt->
lchild=bt->
rchild=NULL;
memset(bt->
data,'
sizeof(bt->
data));
//memset是计算机中C/C++语言函数——memset(void*s,intch,size_tn);
//将s所指向的某一块内存中的后n个字节的内容全部设置为ch指定的ASCII值,
//第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作,其返回值为s。
dflag=1;
//默认bt为叶子节点(即,存放操作数)
//合法性检查
if(*p=='
+'
||*p=='
*'
/'
.'
)'
)//表达式首不合法;
{
表达式输入错误!
return0;
if(!
(*(p+len-1)=='
||*(p+len-1)>
0'
&
*(p+len-1)<
9'
))//不为右
括弧或数字,则表达式尾不合法;
表达式输入错误!
if(len==1)//此时只有表达式为数字,表达式才合法
if(*p<
'
||*p>
){
return0;
bt->
data[0]=*p;
return1;
elseif(len==2)//此时只有表达式为正数或负数,表达式才合法
if((*p=='
-'
||*p>
*p<
)&
*(p+1)>
*(p+1)<
{
bt->
data[1]=*(p+1);
//表达式合法,开始创建二叉树
if(*p=='
('
lnum++;
for(i=1;
i<
len;
i++)
//合法性检查
if(*(p+i)=='
{
if(!
(*(p+i-1)>
*(p+i-1)<
))
{
printf("
return0;
}
}
elseif(*(p+i)=='
||*(p+i)=='
||*(p+i-1)=='
if(lnum==0)rpst1=i;
if(*(p+i-1)=='
||*(p
+i-1)=='
lnum++;
else{
||*(p+i-1)>
lnum--;
if(lnum<
0){
if(*(p+i)=='
!
||*(p+i
-1)=='
elseif(*(p+i)=='
||
*(p+i-1)=='
if(lnum==0)
rpst2=i;
if(lnum!
=0){
//"
)"
未能完全配对,表达式输入不合法
if(rpst2>
-1)//+-
dflag=0;
//data[]存放操作数
data[0]=*(p+rpst2);
if(CreateBiTree(bt->
lchild,p,rpst2))
if(CreateBiTree(bt->
rchild,p+rpst2+1,len-rpst2-1))
return1;
if(rpst1<
0)//此时表明表达式或者是一个数字,或是表达式整体被一对括弧括起来
if(*p=='
)//此时表达式整体被一对括弧括起来
if(CreateBiTree(bt,p+1,len-2))
elsereturn0;
else
if(*(p+1)!
)//此时表达式一定是一个数字
for(i=0;
{
if(*(p+i)=='
)pn++;
if(pn>
1){
printf("
return0;
}
bt->
data[i]=*(p+i);
}
else//此时表达式首一定是操作符"
其余部分被一对括弧括起来
bt->
data[0]='
if(CreateBiTree(bt->
rchild,p+2,len-3))
return1;
elsereturn0;
else//此时表明表达式为几个因子想成或相除而组成的
data[0]=*(p+rpst1);
lchild,p,rpst1))
rchild,p+rpst1+1,len-rpst1-1))
//计算表达式
rst)
doublel=0,r=0;
//l、r分别存放左右子树所代表的字表达式的值
bt){
rst=0;
if(bt->
dflag==1){
rst=atof(bt->
data);
//atof(),是C语言标准库中的一个字符串处理函数,
//功能是把字符串转换成浮点数,
//所使用的头文件为<
。
该函数名是“asciitofloatingpointnumbers”的缩写。
//语法格式为:
doubleatof(constchar*nptr)。
if(Calculate(bt->
lchild,l))//后序
if(Calculate(bt->
rchild,r))
switch(bt->
data[0])
case'
:
rst=l+r;
break;
rst=l-r;
rst=l*r;
if(r==0){
printf("
除数为0!
return0;
else{
rst=l/r;
break;
default:
return0;
//printf("
%g%c%g=%g\n"
l,bt->
data[0],r,rst);
//输出运算过程
//先序遍历二叉树
intPreOrderTraverse(BiTreebt)
if(bt)
%s"
bt->
if(PreOrderTraverse(bt->
lchild))
if(PreOrderTraverse(bt->
rchild))
return1;
//中序遍历二叉树
intInOrderTraverse(BiTreebt)
if(InOrderTraverse(bt->
if(InOrderTraverse(bt->
//后序遍历二叉树
intPostOrderTraverse(BiTreebt)
if(PostOrderTraverse(bt->
if(PostOrderTraverse(bt->
elsereturn0;
//销