中缀表达式生成二叉树,大概应该有递规,迭代,和编译原理中的自顶向下的预测分析法等。

递规,迭代的思路每次读出一个数字,一个运算符,比较当前运算符和之前符号的优先级,进行相关的操作。

自顶向下的预测分析法,做了下,实在忘记的差不多了,先占个位。以后完成。

tree.c

#include "head.h"struct Node * CreateNodesetV(int number,char opr,int type)
{struct nodeData db;db.numberValue=number;db.operatorValue=opr;db.symbolType=type;struct Node * myNode=malloc(sizeof(struct Node));CreateNode(db,myNode);return myNode;
};void  CreateNode(struct nodeData nd,struct Node * myN)
{myN->NData.numberValue=nd.numberValue;myN->NData.operatorValue=nd.operatorValue;myN->NData.symbolType=nd.symbolType;myN->lchilden='\0';myN->rchilden='\0';
};char insertNode(struct Node * myNode,struct Node * father,char lr)
{char result='Y';if(lr=='L'){if(father->lchilden=='\0'){father->lchilden=myNode;}else{result='N';}}else{if(father->rchilden=='\0'){father->rchilden=myNode;}else{result='N';}}return result;
}//原来树的遍历也就是递归.我去,我说自己怎么老是不得要领.根源在于没想明白递归函数.
void visitTree(struct Node * Root)
{if(Root->lchilden!='\0'){visitTree(Root->lchilden);}else{//终止递归的确定事件,是无事件.
    }if(Root->NData.symbolType==1){printf("%d",Root->NData.numberValue);}else{printf("%c",Root->NData.operatorValue);}if(Root->rchilden!='\0'){visitTree(Root->rchilden);}else{//终止递归的确定事件,是无事件.
    }
}

//所以如果用递归来做运算必须是后序遍历,要等左右树都有结果了,才用符号。
//其实我们的心算和笔算,也是后续遍历。int visitTree_2(struct Node * Root)
{int lvalue;int rvalue;int result;if(Root->lchilden!='\0'){lvalue=visitTree_2(Root->lchilden);}else{return Root->NData.numberValue;}if(Root->rchilden!='\0'){rvalue=visitTree_2(Root->rchilden);}else{return Root->NData.numberValue;}switch (Root->NData.operatorValue){case '+':{result=lvalue+rvalue;break;}case '-':{result=lvalue-rvalue;break;}case '*':{result=lvalue*rvalue;break;}case '/':{result=lvalue/rvalue;break;}}return result;
}

head.h

//treestruct nodeData
{int symbolType; //1: number 2: operatorint numberValue;char operatorValue;
};struct Node
{struct nodeData NData;struct Node * lchilden;struct Node * rchilden;
};char insertNode(struct Node * myNode,struct Node * father,char lr);
struct Node * CreateNodesetV(int number,char opr,int type);
void  CreateNode(struct nodeData nd,struct Node * myN);
void visitTree(struct Node * Root);

1)迭代方法

main.c

  基本思路就是我们手工画图的步骤。写成代码而已。

 每次取一个数字和操作符,对比操作符和之前操作符的优先顺序。状1,大于,则符号为之前树的右子树,数字为符号的左子树。状2,小于,则数字为之前树的右字树,之前树为符号的左子树。
直至最后,只有一个数字符,此数字为之前符号的右子树,
int main()
{char * expression="2+3*5-4/2";//每次取一个数字和操作符,对比操作符和之前操作符的优先顺序。//状1,大于,则符号为之前树的右子树,数字为符号的左子树。//状2,小于,则数字为之前树的右字树,之前树为符号的左子树。//直至最后,只有一个数字符,此数字为之前符号的右子树,char preOpe='#';struct Node * PreNode='\0';struct Node * RootNode='\0';int i=0;int strLen=getStrLen(expression);while(i<strLen){if(i==0)//
        {int cNumber=expression[i]-48;i++;char cOperator=expression[i];i++;struct Node * LeftC=CreateNodesetV(cNumber,' ',1);struct Node * Root=CreateNodesetV(0,cOperator,2);insertNode(LeftC,Root,'L');preOpe=cOperator;PreNode=Root;RootNode=Root;}else{if(i+2<strLen)//get a number and operator
            {int cNumber=expression[i]-48;i++;char cOperator=expression[i];i++;if(lHeight(preOpe,cOperator)==1){struct Node * numberNode=CreateNodesetV(cNumber,' ',1);struct Node * OpeNode=CreateNodesetV(0,cOperator,2);insertNode(OpeNode,PreNode,'R');insertNode(numberNode,OpeNode,'L');preOpe=cOperator;PreNode=OpeNode;}else if (lHeight(preOpe,cOperator)==0){struct Node * numberNode=CreateNodesetV(cNumber,' ',1);struct Node * OpeNode=CreateNodesetV(0,cOperator,2);insertNode(RootNode,OpeNode,'L');insertNode(numberNode,PreNode,'R');preOpe=cOperator;PreNode=OpeNode;RootNode=OpeNode;}}else//last char
            {int cNumber=expression[i]-48;i++;struct Node * numberNode=CreateNodesetV(cNumber,' ',1);insertNode(numberNode,PreNode,'R');}}}if(RootNode!='\0'){visitTree(RootNode);printf("\nresult:%d",visitTree_2(RootNode));}return 0;
}int getStrLen(char * c)
{int i=0;while(c[i]!='\0'){i++;}return i;
}int lHeight(char oldc,char newl)
{if(oldc=='+'||oldc=='-'){if(newl=='*'||newl=='/'){return 1;}}else if(oldc=='#'){return 1;}return 0;
}

2) 递规方式。

尾递规一般是可以用循环迭代来表示。所以这里递规其实并不是很体现优势。

  只是可以锻炼下递规的思路,递规是:把问题难度逐层降低,以至到达某个层次(一般0或1),是个确定的操作不需要递规,那么这个层次的上层的操作也变成了确定操作。以至最终解决问题。

  这里一样的思路:一个表达式很长,我只能解决一个数字,一个操作符,并把他放到之前的树上。剩下的表达式也就是遗留的问题让下层去做。下层能做的事和上面一样。以至到最后,只剩下一个数字,只能防到右叶,遗留的问题,到这里终结。

mian.c

void CreateTree(char * expression,struct Node * PreNode,char preOpe);
struct Node * Root='\0';
int main()
{char * expression="2+3*5-4/2";char preOpe='#';struct Node * PreNode='\0';int strLen=getStrLen(expression);CreateTree(expression,PreNode,preOpe);if(Root!='\0'){visitTree(Root);printf("\nresult:%d",visitTree_2(Root));}return 0;
}void CreateTree(char * expression,struct Node * PreNode,char preOpe)
{int strLen=getStrLen(expression);if(strLen>1){int cNumber=expression[0]-48;char cOperator=expression[1];if(lHeight(preOpe,cOperator)==1){struct Node * numberNode=CreateNodesetV(cNumber,' ',1);struct Node * OpeNode=CreateNodesetV(0,cOperator,2);if(preOpe!='#'){insertNode(OpeNode,PreNode,'R');insertNode(numberNode,OpeNode,'L');preOpe=cOperator;PreNode=OpeNode;}else{insertNode(numberNode,OpeNode,'L');preOpe=cOperator;PreNode=OpeNode;Root=OpeNode;}}else if (lHeight(preOpe,cOperator)==0){struct Node * numberNode=CreateNodesetV(cNumber,' ',1);struct Node * OpeNode=CreateNodesetV(0,cOperator,2);insertNode(Root,OpeNode,'L');insertNode(numberNode,PreNode,'R');preOpe=cOperator;PreNode=OpeNode;Root=OpeNode;}CreateTree(expression+2,PreNode,preOpe);}else{int cNumber=expression[0]-48;struct Node * numberNode=CreateNodesetV(cNumber,' ',1);insertNode(numberNode,PreNode,'R');}
}

3)自顶向下的预测分析。

做了下,没出来。以后看看。

转载于:https://www.cnblogs.com/lsfv/p/5516278.html

中缀表达式生成二叉树相关推荐

  1. PAT甲级1130 Infix Expression:[C++题解]中缀表达式、二叉树中序遍历、dfs

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析:本题是借助中缀表达式这个背景,考察二叉树的中序遍历.本题需要注意的地方是加括号. 左子树和右子树无脑加括号,只要不是叶结点. 所以写d ...

  2. 中缀表达式转换成后缀表达式

    中缀表达式就是我们正常工作中写的表达式,如 a+(b-c)*d ,编译系统将中缀表达式改写 abc-d*+,这种运算符在操作数后面称为后缀表达式(也称逆波兰表达式). 如何实现转换的呢?这里做一下自己 ...

  3. 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放...

    01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...

  4. 【二叉树】二叉树的遍历规则(前序遍历、后序遍历、中序遍历)|前/后/中缀表达式...

    转自:https://www.cnblogs.com/turnips/p/5096578.html 今天看了一些关于平和查找二叉树的问题,顺便也复习了一下二叉树的遍历规则,写一下学习文档. 树的遍历顺 ...

  5. leetcode 282. Expression Add Operators | 282. 给表达式添加运算符(中缀表达式求值)

    题目 https://leetcode.com/problems/expression-add-operators/description/ 题解 中缀表达式求值问题,参考:leetcode 227. ...

  6. 算术表达式的实现,支持加减乘除,括号运算,表达式转二叉树

    基本思路 首先,用户输入的待求表达式,也就是中缀表达式,对于人来说,这个很好理解,但是对于计算机,后缀表达式求值更加容易.如果看成一棵二叉树,其实中缀表达式就是对一个二叉树的中序遍历,后缀表达式(也叫 ...

  7. 将表达式树转换成中缀表达式☆

    题目:请设计一个算法,将给定的表达式树,转换成等价的中缀表达式并输出. 分析:         题目已然说明我们要采取中序遍历,进而输出该表达式,那么需要注意的点便是我们的括号在哪里加,其中根节点处( ...

  8. c语言中缀表达式求值_[源码和文档分享]基于C++的表达式计算求值

    一.使用说明 1.1 项目简介 表达式求值是程序设计语言编译中的一个最基本的问题,就是将一个表达式转化为逆波兰表达式并求值.具体要求是以字符序列的形式从终端输入语法正确的.不含变量的整数表达式,并利用 ...

  9. 中缀表达式转换成前缀表达式和后缀表达式的极其简单方法

    35,15,+,80,70,-,*,20,/ //后缀表达方式 (((35+15)*(80-70))/20)=25 //中缀表达方式 /,*,+,35,15,-,80,70, 20 //前缀表达方式 ...

最新文章

  1. HBase的Shell操作
  2. 用户态程序调用系统态程序-快速系统调用
  3. 如何配置Spring的XML文件及使用
  4. codeforces div2 C. Ehab and a 2-operation task
  5. openshift用户管理_OpenShift Express Web管理控制台:入门
  6. Android手机通讯录解析
  7. Some thoughts on dfs
  8. BZOJ3309 DZY Loves Math(莫比乌斯反演+线性筛)
  9. 17.1 情感分析全貌 意境级
  10. 【产品】保险业务收付管理系统概要
  11. echarts官网打不开。
  12. pool.map()爬取美文网标题内容
  13. js怎么实现那种整体页面变灰色
  14. 中高端时代趁势而来,本就艰难的酒店企业如何顺势而为
  15. 使用 Python 脚本执行国密 sm2 加解密
  16. 常见网络攻击原理及其防御
  17. 【Jenkins+青藤云】基于Jenkins部署青藤云镜像扫描插件(2)—部署问题解决
  18. 如何在IE浏览器中预览文件
  19. Android盒子 摄像头,android tv盒子播放器控制 监听上下左右键。
  20. 【转】VCM驱动IC--close loop

热门文章

  1. 《应届生求职面试全攻略》学习笔记(三)——面试题目分类讲解
  2. android学习笔记(入门篇)
  3. Ubuntu常用APT命令参数
  4. 如果你的船不进来,就游出去迎接它 乔纳森温特斯
  5. spring + angular 实现导出excel
  6. Python开发培训前景如何?
  7. 产品设计体会(9000)人人都是产品经理,系列说明
  8. 安装配置Mysql主从
  9. redis的数据类型及设置方法
  10. 深入理解javascript之this