算术表达式(例题)-二叉树

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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...');readln;halt(1); end;

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=0) do

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;

相关文档
最新文档