表达式树:

       叶子是操作数,其余结点为操作符,是二叉树的其中一种应用

====================我是分割线======================

一棵表达式树如下图: 

  

  若是对它做中序遍历,则可以得到中缀表达式

      做后序遍历,则可以得到后缀表达式

已知树的结点可以表示成

1 struct TreeNode {
2      object element;
3      TreeNode* leftChild;
4      TreeNode* rightChild;
5  };

用后缀表达式构建一棵表达式树:

  思路:(与后缀表达式计算四则运算结构相似)

     1. 一一读入输入字符串

     2. 若是操作数,则初始化为结点后入栈

     3. 若是操作符,则从栈中弹出两个结点(新结点的左右子树),与刚读入的操作符结合起来构建新结点,然后入栈

     重复1~3,最后栈内有一棵表达式树的root结点

code实现:

 1 #include<iostream>
 2 #include <string>
 3 #include<stack>
 4
 5 using namespace std;
 6
 7 struct TreeNode{
 8     char element;
 9     TreeNode* leftChild;
10     TreeNode* rightChild;
11     TreeNode(char ch, TreeNode* l, TreeNode* r) {
12         element = ch;
13         leftChild = l;
14         rightChild = r;
15     }
16     TreeNode() {
17         element = '0';
18         leftChild = 0;
19         rightChild = 0;
20     }
21 };
22
23 //测试函数——输出树
24 void drawTree(TreeNode* root, bool infix) {
25     if (infix) {
26         if (root) {
27             //中序遍历
28             drawTree(root->leftChild, infix);
29             cout << root->element;
30             drawTree(root->rightChild, infix);
31         }
32         else return;
33     }
34     else {
35         if (root) {
36             //后序遍历
37             drawTree(root->leftChild, infix);
38             drawTree(root->rightChild, infix);
39             cout << root->element;
40         }
41         else return;
42     }
43 }
44
45 int main() {
46     string input;
47     stack<TreeNode> expressionTree;
48     while (cin >> input) {
49         if (input == "0") break;
50         for (int i = 0; i < input.size();) {
51             char ch = input[i++];
52             if (ch >= '0' && ch <= '9') {
53                 TreeNode leaves;
54                 leaves.element = ch;
55                 expressionTree.push(leaves);
56             }
57             else {
58                 //出栈,成为新结点右子树
59                 TreeNode* right = new TreeNode(expressionTree.top().element, expressionTree.top().leftChild, expressionTree.top().rightChild);
60                 expressionTree.pop();
61
62                 ////出栈,成为新结点左子树
63                 TreeNode* left = new TreeNode(expressionTree.top().element, expressionTree.top().leftChild, expressionTree.top().rightChild);
64                 expressionTree.pop();
65
66                 //新结点入栈
67                 TreeNode leave(ch, left, right);
68                 expressionTree.push(leave);
69             }
70         }
71         TreeNode* root = &expressionTree.top();
72         expressionTree.pop();
73         drawTree(root, true);
74     }
75     return 0;
76 }
77
78 //NULL 与 0 的概念

局限性

  1. 假设所有输入合法,无空格等非法符号输入

  2. 测试输出函数不能还原优先级,12+3* 的表达式树测试输出将是 1+2*3,而并非(1+2)*3,如果需要,可以在结构体中再加上一个优先级判断,若子结点的操作符优先级小于父结点,则输出时子树的表达式需要最后要整体放到一个括号内。

一些bugs:

  关于NULL、0 和 nullptr的学习

    1. NULL是宏

    2. C中对于NULL的定义为 #define NULL ((void *)0)

    3. C++中对于NULL的定义为0

      #ifdef __cplusplus
      #define NULL 0
      #else
      #define NULL ((void *)0)
      #endif

    4. C++11中对于nullptr的定义      

 1 const
 2 class nullptr_t
 3 {
 4 public:
 5     template<class T>
 6     inline operator T*() const
 7         { return 0; }
 8
 9     template<class C, class T>
10     inline operator T C::*() const
11         { return 0; }
12
13 private:
14     void operator&() const;
15 } nullptr = {};

    

    5. 由于C++中的定义,在重载函数时容易出错

 1 //NULL  0   nullptr
 2 #include <iostream>
 3 #include <stdio.h>
 4
 5 using namespace std;
 6
 7 int f(void* ptr) {
 8     return 2;
 9 }
10
11 int f(int num) {
12     return 3;
13 }
14
15 int main() {
16     int result1 = f(0);
17     //int result2 = f(NULL);
18     int result3 = f(nullptr);
19     cout << "result1 = " << result1 << endl;
20     //cout << "result2 = " << result2 << endl;
21     cout << "result3 = " << result3 << endl;
22     return 0;
23 }

    当我把17行的注释符去掉时:编译错误

    

    最后运行的结果如下:

    

    说明C++11标准中,nullptr的调用在重载时不会又歧义,而0则会在重载时调用int形参的函数

    在C++中,可以的话,尽量用nullptr为空指针赋值

    文章推荐:

      http://www.cppblog.com/airtrack/archive/2012/09/16/190828.html

转载于:https://www.cnblogs.com/cheermyang/p/5288832.html

【C++】朝花夕拾——表达式树相关推荐

  1. lambda表达式树

    一.定义: 表达式树又称为表达式目录树,以数据形式表示语言级代码.所有的数据都存储在树结构中,每个结点表示一个表达式(Expression). 二.要点: –Lambda表达式的参数类型可以忽略,因为 ...

  2. 表达式树 java_Linq表达式树编译非平凡的对象常量,并以某种方式引用它们

    通常,在编译表达式树时,我会想到不是基元类型或字符串的常量是不可能的 . 但是,这段代码: public class A { public int mint = -1; } public static ...

  3. c语言后缀表达式构造二叉树,C ++程序为后缀表达式构造表达式树

    表达式树基本上是用于表示表达式的二叉树.在表达式树中,节点对应于运算符,每个叶节点对应于操作数.这是一个C ++程序,用于按顺序,前顺序和后顺序遍历为后缀表达式构造一个表达式树. 算法Begin Fu ...

  4. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...

    程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少.数据 ...

  5. Lambda表达式和表达式树

    一: Lambda表达式 首先,表达式的类型本身并非委托类型,但它可以通过多种方式隐式或者显式地转换成一个委托实例.匿名函数这个术语同时涵盖了匿名方法和Lambda,很多情况下两者可以使用相互转换原则 ...

  6. 表达式树 php,Linux_LINQ学习笔记:表达式树,构建查询表达式 本节中, 我们 - phpStudy...

    构建查询表达式 本节中, 我们假设我们拥有一个这样的实体类: 1: [Table] public partial class Product 2: 3: { 4: 5: [Column(IsPrima ...

  7. 表达式树amp;amp;无根树转化为有根树

    //将无根树转化为有根树 vector<int>g[maxn]; void read-tree() { int u,v; scanf("%d",&n); for ...

  8. 干货!表达式树解析框架(3)

    最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 这应该是年前最后一篇了,接下来的时间就要陪陪老婆孩子了 关于表达 ...

  9. C#复习笔记(4)--C#3:革新写代码的方式(Lambda表达式和表达式树)

    Lambda表达式和表达式树 先放一张委托转换的进化图 看一看到lambda简化了委托的使用. lambda可以隐式的转换成委托或者表达式树.转换成委托的话如下面的代码: Func<string ...

最新文章

  1. kafka异步推送设置重试_一篇文章了解 Kafka 幂等性的原理及实践
  2. 人工智能乌托邦 迪拜认为2071年人类应该这样生活!
  3. python发带附件的中文邮件
  4. 科大讯飞2位董事同日辞职,联合创始人胡郁发力造芯
  5. 深度学习核心技术精讲100篇(七十七)-主流推荐引擎技术及优缺点分析
  6. MAT之PCA:利用PCA(四个主成分的贡献率就才达100%)降维提高测试集辛烷值含量预测准确度并《测试集辛烷值含量预测结果对比》
  7. 狗蛋(驱动小白)和老王(硬件老司机)关于硬件那点事儿的一次密谈
  8. 工业级POE交换机技术优势及供电方法详解!
  9. 前端学习(1646):前端系列实战课程之右下角悬浮功能实现思路
  10. linux如何脚本监控tps,通过shell脚本监控日志切换频率
  11. 传相互宝或于6月11日被关停 蚂蚁集团回应:假消息
  12. C/C++-获取成员变量的指针
  13. Spring Cloud Netflix之Eureka上篇
  14. docker容器内安装ifconfig netstat ping vim 等测试工具的方法
  15. django admin 登陆快速添加验证码功能
  16. 如何判断一个数为无符号数还是有符号数
  17. 【转】Google Chrome中顺时针/逆时针滚动圆的含义
  18. 苹果手机屏幕突然变暗_手机突然屏幕失灵
  19. 综合布线系统工程中计算机插座的标识符号是,TD是综合布线系统工程中计算机插座的标识符号。...
  20. FastDNS中修改IP地址

热门文章

  1. [云计算]网线的标签格式
  2. [Hive]Hive表开启事务
  3. lr中错误解决方法(收集)
  4. 吸猫就吸Tomcat之Pipeline-Valve巧妙设计
  5. PHP之内置web服务器
  6. (转)SQL Server数据库状态监控 - 作业状态
  7. 【Windows编程】系列第六篇:创建Toolbar与Statusbar
  8. 在fmri研究中,cca的应用历史
  9. Java 建模:子整体软件开发
  10. mybatis数据库连接池介绍和源码剖析