二叉树求表达式的值

(一)实验目的本实验以二叉树的创建与访问算法设计作为实验内容,掌握树型结构的实现方法,培养解决负责问题的能力。

(二)实验内容1、编写生成二叉树的函数,二叉树的元素从键盘输入;2、编写在二叉树中输入表达方式的函数;3、编写在二叉树中实现表达方式的值的函数;4、编写遍历并输出二叉树的函数。

(三)实验要求1、掌握树型结构的机器内表示;2、掌握树型结构之上的算法设计与实现;3、列表对比分析两种数据结构的相应操作的时间复杂度、空间复杂度,阐明产生差异的原因。

(四)实验设计思路实验采用递归创建二叉树的表达,并实现了后序遍历二叉数表达式,既逆波兰表达式的输出,编写函数计算表达式的值,并输出。

对实验题目进行细分,逐一实现函数预期的功能,如下图,先序输入创建二叉树表达式:+*-99##89##2##/66##3##实验报告(一)部分算法流程图1先序创建二叉树表达式(五)程序清单#i n c l u d e<s t d i o.h>#i n c l u d e<s t d l i b.h>#i n c l u d e<s t r i n g.h>#d e f i n e l e n20#d e f i n e N U L L0s t r u c t t r e e{c h a rd a t a[le n];t r e e*l c h i l d,*r c h i l d;};v o i d c r e a t e t r e e(t r e e*&t r e)//创建二叉树{c h a r c h[l e n];s c a n f("%s",c h);g e t c h a r();i f(s t r c m p(c h,"#")==0)t r e=N U L L;e l s e{t r e=(t r e e*)m a l l o c(s i z e o f(t r e e));s t r c p y(t r e->d a t a,c h);c r e a t e t r e e(t r e->l c h i l d);c r e a t e t r e e(t r e->r c h i l d);}}v o i d i n p u t t r e e(t r e e*t r e)//输出二叉树{i f(t r e!=N U L L){p r i n t f("%s",t r e->d a t a);i f(t r e->l c h i l d!=N U L L||t r e->r c h i l d!=N U L L){p r i n t f("(");i n p u t t r e e(t r e->l c h i l d);i f(t r e->r c h i l d!=N U L L)p r i n t f(",");i n p u t t r e e(t r e->r c h i l d);p r i n t f(")");}}}v o i d t r a v e r s e t r e e(t r e e*t r e)//后续遍历{i f(t r e!=N U L L){t r a v e r s e t r e e(t r e->l c h i l d);t r a v e r s e t r e e(t r e->r c h i l d);p r i n t f("%s",t r e->d a t a);}}v o i d i n o r d e r t r a v e r s(t r e e*t r e)//中续遍历{i f(t r e!=N U L L){t r a v e r s e t r e e(t r e->l c h i l d);p r i n t f("%s",t r e->d a t a);t r a v e r s e t r e e(t r e->r c h i l d);}}d o u b le s o l u t i o n(t r e e*t r e)//二叉树表达式求值{i f(t r e->l c h i l d==N U L L&&t r e->r c h i l d==N U L L&&t r e->d a t a[0]>='0'&&t r e->d a t a[0]<='9')r e t u r n a t o f(t r e->d a t a);e l s e{s w i t c h(t r e->d a t a[0]){c a s e'*':r e t u r ns o l u t i o n(t r e->l c h i l d)*s o l u t i o n(t r e->r c h i l d);c a s e'-':r e t u r ns o l u t i o n(t r e->l c h i l d)-s o l u t i o n(t r e->r c h i l d);c a s e'+':r e t u r ns o l u t i o n(t r e->l c h i l d)+s o l u t i o n(t r e->r c h i l d);c a s e'/':r e t u r ns o l u t i o n(t r e->l c h i l d)/s o l u t i o n(t r e->r c h i l d);}}}i n t m a i n(){t r e e*t r e;d o u b le s u m;i n t c h;d o{p r i n t f("………………选择下面功能……………………\n");p r i n t f(" 1.先序创建二叉数表达式\n");p r i n t f(" 2.后序遍利二叉数表达式\n");p r i n t f(" 3.求二叉数表达式的数值\n");p r i n t f(" 4.中序遍利二叉数表达式\n");p r i n t f(" 5.退出二叉数\n");p r i n t f("……………………………………………………\n");s c a n f("%d",&c h);s w i t c h(c h){c a s e1:p r i n t f("输入创建的二叉树:\n");g e t c h a r();c r e a t e t r e e(t r e);i n p u t t r e e(t r e);p r i n t f("\n");b r e a k;c a s e2:p r i n t f("后序遍历的二叉树:\n");t r a v e r s e t r e e(t r e);p r i n t f("\n");b r e a k;c a s e3:s u m=s o l u t i o n(t r e);p r i n t f("二叉树表达式的值为=%l f\n",s u m);b r e a k;c a s e4:p r i n t f("中序遍历的二叉树:\n");i n o r d e r t r a v e r s(t r e);p r i n t f("\n");b r e a k;c a s e5:b r e a k;}}w h i l e(c h!=5);r e t u r n0;}(六)实验结果………………选择下面功能……………………1.先序创建二叉数表达式2.后序遍利二叉数表达式3.求二叉数表达式的数值4.中序遍利二叉数表达式5.退出二叉数 (1)输入创建的二叉树:+*-99##89##2##/66##3##+(*(-(99,89),2),/(66,3))………………选择下面功能……………………1.先序创建二叉数表达式2.后序遍利二叉数表达式3.求二叉数表达式的数值4.中序遍利二叉数表达式5.退出二叉数 (2)后序遍历的二叉树:9989-2*663/+………………选择下面功能……………………1.先序创建二叉数表达式2.后序遍利二叉数表达式3.求二叉数表达式的数值4.中序遍利二叉数表达式5.退出二叉数……………………………………………………4中序遍历的二叉树:9989-2*+663/………………选择下面功能……………………1.先序创建二叉数表达式2.后序遍利二叉数表达式3.求二叉数表达式的数值4.中序遍利二叉数表达式5.退出二叉数……………………………………………………3二叉树表达式的值为=42.000000………………选择下面功能……………………1.先序创建二叉数表达式2.后序遍利二叉数表达式3.求二叉数表达式的数值4.中序遍利二叉数表达式5.退出二叉数……………………………………………………5请按任意键继续. . .(七)实验遇到的问题二叉树的递归创建只能先序创建吗?若采用中序或后序创建,必须先输入左子树,我们所定义二叉树往电脑输入时,必须有终止条件,比如if(strcmp(ch,"#")==0)tre=NULL;所以,一颗二叉树中序或后序建立时,必先输入左子树,而左子树是终止条件,所以,无法建立一颗二叉树。

合集下载

实验五 二叉树的应用----表达式求值

实验五  二叉树的应用----表达式求值

浙江大学城市学院实验报告课程名称python高级程序设计实验项目名称实验五二叉树的应用----表达式求值实验成绩指导老师(签名)日期一.实验目的和要求1、掌握二叉树的链式存储结构;2、掌握在二叉链表上的二叉树的基本操作;3、掌握二叉树的简单应用----表达式树的操作。

二.实验内容1、在实验四中,已经实现了对一个中缀表达式可以用栈转换成后缀表达式,并可对后缀表达式进行求值计算的方法。

另一种思路是可以利用二叉树建立表达式树,通过对该表达式树进行求值计算,本实验实现:输入一个中缀表达式,建立该表达式的二叉树,然后对该二叉树进行表达式值的计算。

如一个中缀达式(6+2)*5 的二叉树表示为如下所示时,该二叉树的后序遍历62+5*正好就是后缀表达式。

设一般数学表达式的运算符包括+、-、*、/ 四种,当然允许(),且()优先级高。

为方便实现,设定输入的表达式只允许个位整数。

要求设计一个完整的程序,对输入的一个日常的中缀表达式,实现以下功能:⏹建立对应的二叉树⏹输出该二叉树的前序序列、中序序列、后序序列⏹求该二叉树的高度⏹求该二叉树的结点总数⏹求该二叉树的叶子结点数⏹计算该二叉树的表达式值分析:(1)表达式树的构建方法:●构建表达式树的方法之一:直接根据输入的中缀表达式构建对于任意一个算术中缀表达式,都可用二叉树来表示。

表达式对应的二叉树创建后,利用二叉树的遍历等操作,很容易实现二叉树的求值运算。

因此问题的关键就是如何创建表达式树。

对于一个中缀表达式来说,其表达式对应的表达式树中叶子结点均为操作数,分支结点均为运算符。

由于创建的表达式树需要准确的表达运算次序,因此,在扫描表达式创建表达式树的过程中,当遇到运算符时不能直接创建结点,而应将其与前面的运算符进行优先级比较,根据比较结果进行处理。

这种处理方式在实验四中以采用过,可以借助一个运算符栈,来暂存已经扫描到的还未处理的运算符。

根据表达式树与表达式对应关系的递归定义,每两个操作数和一个运算符就可以建立一棵表达式二叉树,而该二叉树又可以作为另一个运算符结点的一棵子树。

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

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

实验报告课程名称: 程序设计与数据结构 指导老师: ljq 成绩: 实验名称:基于二叉树结构的表达式求值算法 实验类型: 上机 同组学生姓名:一、实验目的和要求(必填)三、代码缺陷及修正记录五、讨论、心得二、实验内容和代码(必填) 四、实验结果与分析(必填)一、实验目的和要求1. 掌握编程工具的使用2. 掌握二叉树数据结构在计算机上的实现3. 掌握通过计算机编程解决问题的基本方法二、实验内容和代码1.实验内容:● 编程实现基于二叉树结构的表达式求值算法● 表达式包含加减乘除四则运算以及至少一层括弧运算● 首先将输入的原表达式转换成二叉树结构,然后采用二叉树的后序递归遍历方法求得表达式的值● 将所有实验内容合并到一个工程,增加交互操作和循环处理(持续)2.代码1.头文件expnbitree .h装订 线1 2 3 4 5 6 7 8 91011121314151617181920212223 #include<stdio.h>#include<string.h>#include<stdlib.h>#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); //销毁二叉树//二叉树结构的表达式求解算法入口void expnbitree();2.源文件expntree.c1 2 3 4 5 6 7 8 910111213141516 #include<stdio.h>#include<string.h>#include<stdlib.h>#include"expnbitree.h"//ExpnBiTree实现子程序入口void expnbitree(){int n, len, i; //n标志量,值为0,退出程序;len存储表达式的长度;i一般变量char expn[EXP_LEN + 1]; //存放表达式double rst; //存放表达式计算结果BiTree bt = NULL; //声明一个二叉树gets_s(expn);do{1718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 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;}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);elseprintf("计算表达式的值失败!\n");printf("即将销毁二叉树…………");if (DestroyBiTree(bt))printf("二叉树销毁成功!\n");else {printf("二叉树销毁失败!\n");exit(0);}printf("如果要继续计算下一个表达式,请输入1,否则,返回上一级:\n ");616263646566676869707172737475767778798081828384858687888990919293949596979899 100 101 102 103 104scanf_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{//初始化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。

基于二叉树的表达式求值算法实验报告

基于二叉树的表达式求值算法实验报告

基于二叉树的表达式求值算法实验报告一、实验目的1. 学习基于二叉树的表达式求值算法。

2. 掌握二叉树的遍历方法和递归算法。

3. 设计并实现基于二叉树的表达式求值程序。

二、实验环境操作系统:Windows 10开发环境:Visual Studio Code 1.57.1编程语言:C++三、算法描述1. 表达式转二叉树将中缀表达式转换为二叉树的过程可以通过递归算法实现。

具体步骤如下:(1)如果表达式只有一个数字,那么将其作为叶子节点返回。

(2)如果表达式包含多个操作符,则以操作符优先级最低的操作符为根节点,将表达式分成两部分,分别递归处理左子树和右子树。

(3)如果表达式中有括号,则将括号中的表达式作为一棵子树递归处理。

2. 表达式求值二叉树求值的过程可以通过递归算法实现。

对于一个二叉树节点,分别计算其左子树和右子树的值,并根据节点的操作符计算节点的值。

具体步骤如下:(1)如果节点是叶子节点,则其值为对应数字。

(2)如果节点是加法节点,则将左右子树的值相加。

(3)如果节点是减法节点,则将左子树的值减去右子树的值。

(4)如果节点是乘法节点,则将左右子树的值相乘。

(5)如果节点是除法节点,则将左子树的值除以右子树的值。

四、实验步骤1. 定义二叉树节点结构体c++struct node {char oper; 节点的操作符double val; 节点的值node* left; 左子树节点node* right; 右子树节点};2. 实现表达式转二叉树函数c++node* expressionToTree(string exp) { int len = exp.length();node* root = NULL;如果表达式是一个数字if (len == 1) {root = new node;root->oper = '#';root->val = exp[0] - '0';root->left = NULL;root->right = NULL;return root;}如果表达式包含多个操作符int pos = 0, priority = 0;for (int i = 0; i < len; i++) {if (exp[i] == '(') {priority += 10;continue;}if (exp[i] == ')') {priority -= 10;continue;}if (exp[i] == '+' exp[i] == '-') {if (priority <= 1) {root = new node;root->oper = exp[i];root->left = expressionT oTree(exp.substr(pos, i - pos));root->right = expressionToTree(exp.substr(i + 1));return root;}}if (exp[i] == '*' exp[i] == '/') {if (priority <= 2) {root = new node;root->oper = exp[i];root->left = expressionT oTree(exp.substr(pos, i - pos));root->right = expressionToTree(exp.substr(i + 1));return root;}}}return root;}3. 实现表达式求值函数c++double evaluate(node* root) {if (root == NULL) return 0.0;if (root->left == NULL && root->right == NULL) return root->val;double left_val = evaluate(root->left), right_val =evaluate(root->right);switch (root->oper) {case '+': return left_val + right_val;case '-': return left_val - right_val;case '*': return left_val * right_val;case '/': return left_val / right_val;default: return 0.0;}}4. 测试程序c++int main() {string exp = "((5-2)*(3+4))/7";node* root = expressionToTree(exp);cout << exp << " = " << evaluate(root) << endl; 输出结果为3 return 0;}五、实验结果分析本实验设计并实现了基于二叉树的表达式求值程序。

二叉树表达式求值

二叉树表达式求值
{
switch(str1)
{
case '#':case'(':case'[':return 0;break;
case '*':case '/':return 1;break;
case '+':case'-':switch(str2)
{
case '+':case'-':case'#':return 1;break;
}
pushstack1(L1,p[i]);
break;
}
}
i++;
}
popstack2(L2,T);
return T;
}
//后序遍历表达式树
void postorder(BiTree T)
{
if(T)
{
postorder(T->lchild);
printf("后缀式为:");
postorder(T);
printf("\n");
printf("前缀式为");
midorder(T);
printf("\n");
printf("结果为:");
printf("%.3f\n",T->data2);
}
{
while(indigit(p[i]))
{
str[j++]=p[i];
i++;

二叉树计算表达式

二叉树计算表达式

二叉树计算表达式计算表达式是计算机科学中常见的任务,而二叉树是一种常用的数据结构,用于表示表达式。

本文将介绍二叉树如何表示和计算表达式。

一、二叉树表示表达式二叉树是由节点和边组成的树状结构。

每个节点都包含一个值和两个指向左右子节点的指针。

二叉树可以用来表示数学表达式。

例如,下面是一个包含加、减、乘、除的表达式:```5 + 3 *6 / 2 - 4```将表达式转化为二叉树表示,根节点为`-`,其左子树是`+`,右子树是`4`。

`+`节点的左子树为`5`,右子树为`/`。

`/`节点的左子树为`*`,右子树为`2`。

`*`节点的左子树为`3`,右子树为`6`。

```-/ \+ 4/ \5 // \* 2/ \3 6```每个节点的值表示该节点的操作符或操作数。

叶子节点是操作数,内部节点是操作符。

二、计算二叉树表达式计算表达式需要递归地对二叉树进行遍历。

从根节点开始,如果是操作符节点,就对其左右子节点进行递归。

如果是操作数节点,就返回该节点的值。

等到递归完成后,就可以根据操作符节点的值和左右子节点的值对表达式进行计算了。

对于上面的表达式二叉树,计算的过程如下。

首先计算根节点的左右子节点,即`+`节点和`4`节点的值。

`+`节点还需要计算其左右子节点`5`和`/`节点的值。

`/`节点又需要计算其左右子节点`*`和`2`的值。

`*`节点需要计算其左右子节点`3`和`6`的值。

归纳起来,计算的顺序是从下到上,从左到右。

```-/ \+ 4/ \5 // \* 2/ \3 6```按照计算顺序求值:1. 计算`3 * 6`,得到18。

2. 计算`6 / 2`,得到3。

3. 计算`3 / 3`,得到1。

4. 计算`5 + 1`,得到6。

5. 计算`6 - 4`,得到2。

因此,表达式`5 + 3 * 6 / 2 - 4`的值是2。

三、扩展上面的例子说明了如何将表达式转为二叉树,并计算表达式的值。

但实际中会有更复杂的表达式,如函数调用、变量引用等。

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

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

最早提出遍历问题的是对存储在计算机中的表达式求值。

例如:(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;右界初值为串长度。

③ 判断左右括号是否匹配,不匹配则认为输入有错误。

④ 在表达式的左右界范围内寻找运算级别最低的运算符,同时判断运算符两旁有否参与运算的变量或数。

若无,则输入表达式不合法;若有,作为当前子树的根结点,设置左子树指针及其左右界值,设置右子树指针及其左右界值。

⑤ 若表达式在左右界范围内无运算符,则为叶子结点,判断变量名或数是否合法。

⑥ 转④,直到表达式字符取完为止。

二叉链表求算数表达式

二叉链表求算数表达式二叉链表是一种常见的数据结构,用于表示二叉树。

在算术表达式求值中,也可以利用二叉链表来表示算术表达式的结构,方便进行计算和操作。

二叉链表表示算术表达式的方式是将表达式转化为二叉树的形式。

其中,二叉树的叶子节点存储操作数,内部节点存储运算符。

通过遍历二叉树,可以按照特定的规则解释算术表达式并求值。

下面是一个示例,展示如何将算术表达式转化为二叉链表:算术表达式: 2 + 3 * 41. 将运算符和操作数转化为节点,并建立二叉链表:```+/ \2 */ \3 4```2. 通过遍历二叉链表,按照运算符的优先级求值。

首先,遍历左子树进行运算,得到:2然后,遍历右子树进行运算,得到:3 * 4 = 12最后,根据根节点的运算符进行运算,得到:2 + 12 = 14算术表达式的求值过程可以通过二叉链表的先序遍历来实现,具体步骤如下:1. 如果节点是叶子节点(操作数),返回操作数的值。

2. 如果节点是内部节点(运算符),获取左子树和右子树的值。

3. 根据运算符进行相应的运算,并返回结果。

示例的先序遍历过程如下:先序遍历:+ 2 * 3 41. 访问根节点:+2. 访问左子树:23. 访问右子树的左子树:*4. 访问右子树的左子树:35. 访问右子树的右子树:4经过先序遍历的过程,可以逐步解释算术表达式并求值。

二叉链表表示算术表达式的方法在编译原理中得到了广泛的应用。

通过将表达式转化为二叉树的形式,可以方便地进行运算和求值。

在实际应用中,可以使用栈来实现二叉链表表示的算术表达式的求值,具体步骤如下:1. 遍历表达式的每个字符。

2. 如果字符是操作数,将其转化为节点并入栈。

3. 如果字符是运算符,取栈顶的两个节点作为右子树和左子树,将运算符作为根节点,再入栈。

4. 最终栈中只会剩下一个节点,即根节点。

通过这种方式,可以将表达式转化为二叉链表,并计算出最终的结果。

总结起来,二叉链表可以用来表示算术表达式的结构,并进行求值。

后序遍历二叉树实现表达式求值

关键词 :中缀表达式 ; 后序遍历 ;表达式求值 中 图分类号 :T P 3 1 文献标识 码 : A
表达式求值是数据结构 中常见的问题 , 传统的求值方法效率较低. 本文 以逻辑运算为例 , 采用 二叉树 作为表达式的存储结构… , 对二叉树进行后序遍历来实现表达式求值 , 提高了运算效率. 尤其适用于对 同
一
表 达式 中的变 量赋 予 多组 不 同初值 的情 况 , 比如判 断 表达 式 的 类 型 、 求 解 表 达 式 的成 真 赋值 等 , 从 而 可
扩展 应用 到 逻辑 问题 解决 方 案 的求解 等 领域 中.
1 算法设计
运用 二叉 树 实现 表达 式求 值 需解 决 两 个 大 问题 : 表 达 式 的存 储 与 表 达式 求 值 . 本 文 约定 以逻 辑 运 算 为例 , 分别 用 “ &” 、 “ I ” 、 “一” 表示与、 或、 非 三种 逻辑 运算 . 第一 , 表 达式 存储 算 法设计 . 表 1 算符优先关系表
0 1
0 0
O 1
Байду номын сангаас
为“ 与” 运算的运算规则 , 其他运算类似. ( 2 ) 表达式求值.
求值 过程 中只需建 立一个 存放 操作 数 的栈 即可 . 首先 应 该 明确 一 点 : 在存 储 了表 达式 的二叉 树 中 , 操 作 数都 是 叶子结点 , 运算 符都 是分 支结 点. 后 序遍 历该 二叉 树 , 遵循“ 左~ 右一 中” 的顺 序访 问二叉 树 的各
收 稿 日期 : 2 0 1 4 . 1 1 — 1 3
作 者简介 : 潘风 ( 1 9 8 l 一) , 女, 黑龙 江黑 河人 , 运城学 院计 算机科 学与 技术 系讲师 , 工学 硕士 , 主要 从事 网络技术 及应用 方

c语言基于二叉树的表达式求值算法

c语言基于二叉树的表达式求值算法C语言中,基于二叉树的表达式求值算法主要包括两部分:中缀表达式转换为后缀表达式和后缀表达式求值。

1.中缀表达式转换为后缀表达式中缀表达式是我们常见的数学表达方式,例如3 + 4 * 2 - 5。

为了方便计算机求值,我们需要将中缀表达式转换为后缀表达式,也叫做逆波兰表达式。

转换的过程使用栈数据结构来实现。

具体算法如下:1.定义一个栈和一个结果字符串,栈用于存储操作符,结果字符串用于保存后缀表达式。

2.从左到右遍历中缀表达式的每一个字符。

3.如果当前字符是数字,直接将其加入结果字符串。

4.如果当前字符是左括号"(",将其入栈。

5.如果当前字符是右括号")",则依次将栈顶的操作符弹出并加入结果字符串,直到遇到左括号为止,同时将左括号从栈中弹出。

6.如果当前字符是操作符,需要将栈中优先级比当前操作符高或者相等的操作符弹出并加入结果字符串,然后将当前操作符入栈。

7.遍历完所有字符后,将栈中剩余的操作符依次弹出并加入结果字符串。

8.最终结果字符串就是后缀表达式。

例如,对于中缀表达式3 + 4 * 2 - 5,转换为后缀表达式为3 4 2 * + 5 -2.后缀表达式求值后缀表达式求值算法使用栈数据结构来实现。

具体算法如下:1.定义一个栈,用于存储操作数。

2.从左到右遍历后缀表达式的每一个字符。

3.如果当前字符是数字,则将其转换为对应的整数并入栈。

4.如果当前字符是操作符,则从栈中弹出两个操作数,先弹出的作为右操作数,后弹出的作为左操作数,根据操作符进行运算,得到结果后入栈。

5.遍历完所有字符后,栈顶的数字即为最终的结果。

例如,对于后缀表达式3 4 2 * + 5 -,求值的过程如下:1.入栈3。

2.入栈4。

3.入栈2。

4.弹出2和4,计算4 * 2 = 8,将8入栈。

5.弹出8和3,计算3 + 8 = 11,将11入栈。

6.入栈5。

7.弹出5和11,计算11 - 5 = 6,得到最终结果。

利用二叉树求表达式的值

利⽤⼆叉树求表达式的值利⽤⼆叉树求表达式的值,⾸先要注意表达式中先乘除后加减的运算顺序,所以在建⽴树的过程中,就要将加减尽量作为根节点,最后⼀个加减号作为根节点。

建完树之后是运算过程,采⽤树的后序遍历来运算。

⼆叉树的节点结构,其中值的类型⽤char型struct node{char data;node* left;node* right;};node *CRTree(char s[],int begin,int end){node *p;int k,plus=0,posi;if (begin==end) //只有⼀个字符,构造的是⼀个叶⼦节点{p=(node *)malloc(sizeof(node)); //分配存储空间p->data=s[begin]; //值为s[begin]p->left=NULL;p->right=NULL;return p;}//以下为begin!=end的情况for (k=begin; k<=end; k++)if (s[k]=='+' || s[k]=='-'){plus++;posi=k; //最后⼀个+或-的位置}if (plus==0) //没有+或-的情况(因为若有+、-,前⾯必会执⾏plus++)for (k=begin; k<=end; k++)if (s[k]=='*' || s[k]=='/'){plus++;posi=k;}//以上的处理考虑了优先将+、-放到⼆叉树较⾼的层次上//由于将来计算时,运⽤的是后序遍历的思路//处于较低层的乘除会优先运算//从⽽体现了“先乘除后加减”的运算法则//创建⼀个分⽀节点,⽤检测到的运算符作为节点值if (plus!=0){p=(node *)malloc(sizeof(node));p->data=s[posi]; //节点值是s[posi]p->left=CRTree(s,begin,posi-1); //左⼦树由s[begin]⾄s[posi-1]构成p->right=CRTree(s,posi+1,end); //右⼦树由s[posi+1]到s[end]构成return p;}else//若没有任何运算符,返回NULLreturn NULL;}下⾯是运算过程double Comp(node *b){double v1,v2;if (b==NULL)return0;if (b->left==NULL && b->right==NULL) //叶⼦节点,应该是⼀个数字字符(本项⽬未考虑⾮法表达式)return b->data-'0'; //叶⼦节点直接返回节点值,结点中保存的数字⽤的是字符形式,所以要-'0'v1=Comp(b->left); //先计算左⼦树v2=Comp(b->right); //再计算右⼦树switch(b->data) //将左、右⼦树运算的结果再进⾏运算,运⽤的是后序遍历的思路{case'+':return v1+v2;case'-':return v1-v2;case'*':return v1*v2;case'/':if (v2!=0)return v1/v2;elseabort();}}最后要记得将新建的⼆叉树销毁void DestroyBTNode(node *&b) //销毁⼆叉树{if (b!=NULL){DestroyBTNode(b->left);DestroyBTNode(b->right);free(b);}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档