ImageVerifierCode 换一换
格式:DOCX , 页数:34 ,大小:231.37KB ,
资源ID:5825862      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5825862.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(题目设计一个程序实现基于二叉树表示的算术表达式的操作.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

题目设计一个程序实现基于二叉树表示的算术表达式的操作.docx

1、题目设计一个程序实现基于二叉树表示的算术表达式的操作题目:设计一个程序实现基于二叉树表示的算术表达式的操作。一、 需求分析1、以二叉树为基本模型,构建了表达式二叉树。算术表达式的合法输入数据包括变量(,az)、常量(09)和二元运算符(,(乘幂),一元运算符(sin, cos,tan)。演示程序以人机对话的方式执行,即在计算机上显示提示信息后,由用户在键盘上输入对应的数据或命令,程序将执行相应的操作并显示下一步信息。表达式的输出主要是用带括号的中缀表示式输出调用函数InorderExp( ExpTree E, Status ( * Visit )( ExpTree e ) );2、 程序的目的

2、实现算术表达式在计算机里的树形存储,实现基本的运算(,(乘幂)sin,cos,tan),求偏导,常数合并。3、 测试数据( 附后 )。提供两种方式的测试:一种是自动测试,即程序调用test文件夹data.txt文件里的测试数据,另一种方式是手动测试,即按程序提示一步一步输入测试。除了满足要求的0; a; -91; +a*bc; +*5x2*8x; +*3x3*2x2x6,还有几十组数据测试。每当输入一个表达式后,程序提示用户赋值,再对表达式求值。为了方便用户,我在程序中用数组保存着一些测试数据,以供测试用。二、概要设计1以字符串保存输入的字符序列。2提示用户赋值的同时将数据取出建立二叉树。3用

3、后根遍历的次序用递归函数对表达式求值,求值时进行相应的转化,将运算数的字符形式转换成整数形式。4用中缀表达式输出表达式时,适当添加括号,以正确反映运算的优先次序。5抽象数据类型的定义:1)、存放表达式的结构类型,是以二叉树为基本原型。typedef enum OPER, VAR, ORD ElemTag;/运算符,变量,常量typedef struct ExpNode ElemTag tag; /标记 union char expr4; /存放运算符名 struct char var; /存放变量名 int val; /存放变量的值,初始值为0 vary; /存放变量 int ordina;

4、/存放常量值 ; struct ExpNode *lchild, *rchild; /* 左右孩子指针 */ *ExpTree; /* 二叉树的二叉链表存储表示 */基本操作:int Random( int nMin, int nMax );/返回nMin到nMax之间的随机数void FindVary( char * c, char * e );/找出表达式中的变量Status ArrayCreateExp( ExpTree &E, char *ch, int &i );/从ch数组中读取字符串,构造表达式void CreateExp( ExpTree &E, char *ch, int &

5、i ) ;/Status InputCreateExp( ExpTree &E ); /从键盘先序输入来构造表达式树TStatus Visit( ExpTree e );/输出e的内容void InorderExp( ExpTree E, Status ( * Visit )( ExpTree e ) );/输出中序表达式用带括号的中缀表示式输出Status Assign( ExpTree E, char v, float c ) ;/对表达式内的所有v,赋值cfloat Value( ExpTree E );/计算表达式的值ExpTree Compound( char p, ExpTree

6、e1, ExpTree e2 );/5.构造一个新的复合表达式(E1)P(E2) Status Diff( ExpTree &E, char V );/求表达式E对变量V的导数void MergeConst( ExpTree E );/合并表达式种所有常数运算Status PreOrderTraverse( ExpTree E, Status ( * Visit )( ExpTree e ) );/波兰式输出Status PostOrderTraverse( ExpTree E, Status ( * Visit )( ExpTree e ) );/逆波兰式输出2)、队列typedef cha

7、r QElemType; typedef struct QNode QElemType data; struct QNode *next;QNode, *QuePtr;typedef struct QuePtr front; QuePtr rear;Queue;基本操作:Status InitQueue( Queue &Q );/构造一个空队列Status DestroyQueue( Queue &Q );/销毁队列Status QueueEmpty( Queue Q );/判空Status EnQueue( Queue &Q, QElemType e );/插入元素e为Q的新的队尾元素Sta

8、tus DeQueue( Queue &Q, QElemType &e );/删除队头元素,用e返回其值,并返回OK,否则返回ERROR;3)、栈typedef struct SElemType *base; SElemType *top; int stacksize;SqStack;基本操作:Status InitStack( SqStack &S );Status StackEmpty( SqStack S );Status Push( SqStack &S, SElemType e );Status Pop( SqStack &S, SElemType &e );SElemType To

9、p( SqStack S );6、 主程序:void main()while(1) 接受命令 处理命令;Switch() case: 1.以数组形式输入前缀表示式函数构造表达式. case: 2.以字符序列输入前缀表示式函数构造表达式. case: 3.实现对变量V的赋值(V=c). case: 4.对算术表达式E求值.n); case: 5.构造一个新的复合表示式(E1)P(E2). case: 6.求偏导函数Diff(E,V) case: 7.对三角函数的测试. case: 8.常数合并. case: 0.结束 三、详细设计1、存放表达式的结构类型,是以二叉树为基本原型。typedef e

10、num OPER, VAR, ORD ElemTag;/运算符,变量,常量typedef struct ExpNode ElemTag tag; /标记 union char expr4; /存放运算符名 struct char var; /存放变量名 int val; /存放变量的值,初始值为0 vary; /存放变量 int ordina; /存放常量值 ; struct ExpNode *lchild, *rchild; /* 左右孩子指针 */ *ExpTree; /* 二叉树的二叉链表存储表示 */我原来是直接用二叉树的存储结构的,后来发现受到这个结构类型的很大限制,受到广义表存储结

11、构的启发,就自己设计了这样一个存储类型。下面分析这个存储结构:(1)、用ElemTag tag;来标记是运算符,变量,常量。用枚举类型定义typedef enum OPER, VAR, ORD ElemTag,可以区分是运算符,变量,常量。(2)、用字符串char expr4; 来存放运算符名,我先预定存放三个字符的运算符名(最后一个char用来存放0),这样运算符不仅可以是+ , - , *,/,还可以是sin,cos,tan。如果觉得三个字符不够,可以扩展。(3)、struct char var; /存放变量名 float val; /存放变量的值,初始为0 vary;/存放变量。这样在变

12、量赋值后,还可以保存着变量名。可以用作如公式一样,重复赋值使用。(4)、使用int ordina;来存放常量值。这样赋值时,就扩大了赋值范围,可以是一个整形的范围,大大扩大了本程序的使用范围。但需要在赋值时使用,在输入时,还是得用09,这也是本程序的缺陷,有待改进。基本操作:int Random( int nMin, int nMax );/返回nMin到nMax之间的随机数void FindVary( char * c, char * e );/找出表达式中的变量Status ArrayCreateExp( ExpTree &E, char *ch, int &i );/从ch数组中读取字符

13、串,构造表达式void CreateExp( ExpTree &E, char *ch, int &i ) ;/Status InputCreateExp( ExpTree &E ); /从键盘先序输入来构造表达式树TStatus Visit( ExpTree e );/输出e的内容void InorderExp( ExpTree E, Status ( * Visit )( ExpTree e ) );/输出中序表达式用带括号的中缀表示式输出Status Assign( ExpTree E, char v, float c ) ;/对表达式内的所有v,赋值cfloat Value( ExpT

14、ree E );/计算表达式的值ExpTree Compound( char p, ExpTree e1, ExpTree e2 );/5.构造一个新的复合表达式(E1)P(E2) Status Diff( ExpTree &E, char V );/求表达式E对变量V的导数void MergeConst( ExpTree E );/合并表达式种所有常数运算Status PreOrderTraverse( ExpTree E, Status ( * Visit )( ExpTree e ) );/波兰式输出Status PostOrderTraverse( ExpTree E, Status

15、( * Visit )( ExpTree e ) );/逆波兰式输出2、队列。typedef char QElemType; typedef struct QNode QElemType data; struct QNode *next;QNode, *QuePtr;typedef struct QuePtr front; QuePtr rear;Queue;基本操作:Status InitQueue( Queue &Q );/构造一个空队列Status DestroyQueue( Queue &Q );/销毁队列Status QueueEmpty( Queue Q );/判空Status E

16、nQueue( Queue &Q, QElemType e );/插入元素e为Q的新的队尾元素Status DeQueue( Queue &Q, QElemType &e );/删除队头元素,用e返回其值,并返回OK,否则返回ERROR;3、栈typedef struct SElemType *base; SElemType *top; int stacksize;SqStack;基本操作:Status InitStack( SqStack &S );Status StackEmpty( SqStack S );Status Push( SqStack &S, SElemType e );St

17、atus Pop( SqStack &S, SElemType &e );SElemType Top( SqStack S );4、主函数和其他主要函数1)、访问函数(输出函数)Status Visit( ExpTree e )/输出e的内容 int m, n5; if( e-tag = OPER ) /运算符 printf(%s, e-expr ); else if( e-tag = VAR ) /变量 if( !e-vary.val ) /变量的值是0 printf(%c, e-vary.var );/输出变量名 else printf(%0.4f, e-vary.val );/输出变量的

18、值 else /常量 if( e-ordina = 0 ) /正数 printf(%d, e-ordina ); else printf(%d), e-ordina ); /负数,输出时加括号 return OK;2)、构造表达式Status ArrayCreateExp( ExpTree &E, char *ch, int &i )/从ch数组中读取字符串,构造表达式 if( chi ) if( ! ( E = ( ExpTree )malloc( sizeof( ExpNode ) ) ) ) return ERROR; if( chi = s & chi+1 = i & chi+2 =

19、n |/sin chi = S & chi+1 = I & chi+2 = N | chi = c & chi+1 = o & chi+2 = s |/cos chi = C & chi+1 = O & chi+2 = S | chi = t & chi+1 = a & chi+2 = n |/tan chi = T & chi+1 = A & chi+2 = N ) E-tag = OPER; E-expr0 = chi; E-expr1 = ch+i; E-expr2 = ch+i; E-expr3 = 0; ArrayCreateExp( E-rchild, ch, +i );/只建右子

20、树 E-lchild = NULL; /左子树为空 return OK; else if( chi = 0 & chi tag = ORD; E-ordina = chi - 0; else if( chi = a & chi tag = VAR; E-vary.var = chi; E-vary.val = 0; else if( chi = + | chi = - | chi = * | chi = / | chi = )/运算符 E-tag = OPER; E-expr0 = chi; E-expr1 = 0; if( ! E-tag ) / E 是运算符 ArrayCreateExp(

21、 E-lchild, ch, +i ); ArrayCreateExp( E-rchild, ch, +i ); else E-lchild = NULL; E-rchild = NULL; return OK;3)、带括号的中缀表示式输出void InorderExp( ExpTree E, Status ( * Visit )( ExpTree e ) )/输出中序表达式用带括号的中缀表示式输出 int bracket; if( E ) if( E-lchild ) bracket = precede( E, E-lchild );/比较双亲与左孩子运算符优先级 if( bracket 0

22、 ) /左孩子优先级低 printf(); InorderExp( E-lchild, Visit ); if( bracket 0 ) printf(); Visit( E ); if( E-rchild ) bracket = precede( E, E-rchild );/比较双亲与右孩子运算符优先级 if( bracket = 0 ) /右孩子优先级低 printf(); InorderExp( E-rchild, Visit ); if( bracket = 0 ) printf(); 4)、计算表达式的值float Value( ExpTree E )/计算表达式的值 float

23、lv,rv,value = 0; if( E ) if( E-tag = VAR ) /是变量 return ( E-vary.val ); if( E-tag = ORD ) return ( E-ordina ); if( E-lchild ) lv = Value( E-lchild ); rv = Value( E-rchild ); switch( E-expr0 ) case +: value = lv + rv; break; case -: value = lv - rv; break; case *: value = lv * rv; break; case /: if( r

24、v ) value = lv / rv; else exit( 0 ); break; case : value = power( lv, rv ); break; case S: case s: value = sin( rv ); break;/sin case T: case t: value = tan( rv ); break;/tan case C: case c: if( E-expr2 = S | E-expr2 = s )/cos value = cos( rv ); break; return ( value );5)、合并常数void MergeConst( ExpTre

25、e E )/合并表达式中所有常数运算 if( ! E-lchild & ! E-rchild ) return; /叶子 if( E-tag = OPER & E-lchild & E-rchild & E-lchild-tag = ORD & E-rchild-tag = ORD ) E-tag = ORD; switch( E-expr0 ) case *: E-ordina = E-lchild-ordina * E-rchild-ordina; break; case /: E-ordina = E-lchild-ordina / E-rchild-ordina; break; cas

26、e : E-ordina = power( E-lchild-ordina, E-rchild-ordina ); break; case +: E-ordina = E-lchild-ordina + E-rchild-ordina; break; case -: E-ordina = E-lchild-ordina - E-rchild-ordina; break; free( E-lchild ); free( E-rchild ); E-lchild = NULL; E-rchild = NULL; else if( E-lchild ) MergeConst( E-lchild );

27、 if( E-rchild ) MergeConst( E-rchild ); 5、构造的表达式如图算术表达式前缀表示:*+ab-cd中缀带括号表示:(a+b)*(c-d)四、 调试分析1、调试过程中遇到了许多问题,下面举几个例子。(1)赋值出错处理在调试赋值函数时发生了“赋值失败的情况”修改前的函数:void FindVary( char *c, char * e )/找出表达式中的变量 int i = -1, j = 0; while( e+i ) if( ei = A & ei = a & ei = z ) i += 2; continue; else cj+ = ei; cj = 0;调试出现下面的情况出现了两次了对X的赋值,原因是我在编写void FindVary( char *c, ch

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1