算术表达式(例题)-二叉树
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最早提出遍历问题的是对存储在计算机中的表达式求值。例如:(a+b ×(c-d))-e/f 。表达式用树形来表示,如图8-11-1所示。运算符在树中放在非终端结点的位置上,操作数放在叶子结点处。
当我们对此二叉树进行先序、中序和后序遍历后,便可得到表达式的前缀、中缀和后缀书写形式:
前缀:-+a*b-cd/ef
中缀:a+b*c-d-e/f 后缀:abcd-*+ef/-
其中,中缀形式是算术表达式的通常形式,只是没有括号。在计算机内,使用后缀表达式易于求值。
例1 输入一个算术表达式,判断该表达式是否合法,若不合法,给出错误信息;若合法,则输出合法表达式的表达式树。 【算法分析】表达式不合法有三种情况:①左右括号不匹配;②变量名不合法;③运算符两旁无参与运算的变量或数。
分析表达式树可以看到:表达式的根结点及其子树的根结点为运算符,其在树中的顺序是按运算的先后顺序从后到前,表达树的叶子为参与运算的变量或数。
表达式树如图8-11-2
处理时,首先找到运算级别最低的运算符“+”作为根结点,继而确定该根结点的左、右子树结点在表达式串中的范围为a 和(b-c)/d ,再在对应的范围内寻找运算级别最低的运算符作为子树的根结点,直到范围内无运算符,则剩余的变量或数为表达式树的叶子。
【算法步骤】
① 设数组ex 存放表达式串的各字符,lt 、rt 作为结点的左右指针,变量left 、right 用于存放每次取字符范围的左、右界。 ② 设置左界初值为1;右界初值为串长度。
③ 判断左右括号是否匹配,不匹配则认为输入有错误。
④ 在表达式的左右界范围内寻找运算级别最低的运算符,同时判断运算符两旁有否参与运算的变量或数。若无,则输入表达式不合法;若有,作为当前子树的根结点,设置左子树指针及其左右界值,设置右子树指针及其左右界值。
⑤ 若表达式在左右界范围内无运算符,则为叶子结点,判断变量名或数是否合法。
⑥ 转④,直到表达式字符取完为止。
源程序中的h 、d 、w 用于存放文本画图时结点的坐标位置。 program exptree; uses crt; type
point=^tree; tree=record
data:string;
lt:point; rt:point; end; var
n,len,k:integer; ex:string;
letters:set of char;
root:point;
procedure error(er:byte); {出错信息提示} begin
write('Enter error:'); case er of
1:writeln('No letter'); 2,3:writeln('No expressint'); 4:writeln('No+,*,-or/'); 5:writeln('No(or)'); end;
write('Press
procedure create(left,right:integer;var p:point); var q:point; k,n:integer;
begin {找运算级别最低的运算符} if ex[left]='(' then begin
n:=left+1;k:=0;
例如,表达式:a+(b-c)/d 运算顺序: ③ ① ② 图8-11-1
图8-11-2 表达式树
while (n
begin
if ex[n]='(' then inc(k);
if ex[n]=')' then dec(k);
inc(n);
end;
if n=right then
begin
dec(right);inc(left);
end;
end;
if right n:=right;k:=0; repeat if ex[n]=')' then inc(k); if ex[n]='(' then dec(k); dec(n); until (((ex[n]='+') or (ex[n]='-')) and (k=0)) or (n if n=left then error(3); if n>left then begin with p^ do begin data:=ex[n]; new(q);lt:=q; new(q);rt:=q; end; create(left,n-1,p^.lt); create(n+1,right,p^.rt); end else {not found '+''-'} begin n:=right; repeat if ex[n]=')' then inc(k); if ex[n]='(' then dec(k); dec(n); until (((ex[n]='*') or (ex[n]='/')) and (k=0)) or (n if n=left then error(3); if n>left then begin with p^ do begin data:=ex[n]; new(q);rt:=q; new(q);lt:=q; end; create(left,n-1,p^.lt); create(n+1,right,p^.rt); end else {only string} begin {求叶子结点的字串} for k:=left to right do if not(ex[k] in letters) then error(1); p^.data:=''; for k:=left to right do p^.data:=p^.data+ex[k]; p^.lt:=nil;