表达式树:

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

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

一棵表达式树如下图: 

  

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

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

已知树的结点可以表示成

 struct TreeNode {
object element;
TreeNode* leftChild;
TreeNode* rightChild;
};

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

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

     1. 一一读入输入字符串

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

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

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

code实现:

 #include<iostream>
#include <string>
#include<stack> using namespace std; struct TreeNode{
char element;
TreeNode* leftChild;
TreeNode* rightChild;
TreeNode(char ch, TreeNode* l, TreeNode* r) {
element = ch;
leftChild = l;
rightChild = r;
}
TreeNode() {
element = '';
leftChild = ;
rightChild = ;
}
}; //测试函数——输出树
void drawTree(TreeNode* root, bool infix) {
if (infix) {
if (root) {
//中序遍历
drawTree(root->leftChild, infix);
cout << root->element;
drawTree(root->rightChild, infix);
}
else return;
}
else {
if (root) {
//后序遍历
drawTree(root->leftChild, infix);
drawTree(root->rightChild, infix);
cout << root->element;
}
else return;
}
} int main() {
string input;
stack<TreeNode> expressionTree;
while (cin >> input) {
if (input == "") break;
for (int i = ; i < input.size();) {
char ch = input[i++];
if (ch >= '' && ch <= '') {
TreeNode leaves;
leaves.element = ch;
expressionTree.push(leaves);
}
else {
//出栈,成为新结点右子树
TreeNode* right = new TreeNode(expressionTree.top().element, expressionTree.top().leftChild, expressionTree.top().rightChild);
expressionTree.pop(); ////出栈,成为新结点左子树
TreeNode* left = new TreeNode(expressionTree.top().element, expressionTree.top().leftChild, expressionTree.top().rightChild);
expressionTree.pop(); //新结点入栈
TreeNode leave(ch, left, right);
expressionTree.push(leave);
}
}
TreeNode* root = &expressionTree.top();
expressionTree.pop();
drawTree(root, true);
}
return ;
} //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的定义      

 const
class nullptr_t
{
public:
template<class T>
inline operator T*() const
{ return ; } template<class C, class T>
inline operator T C::*() const
{ return ; } private:
void operator&() const;
} nullptr = {};

    

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

 //NULL  0   nullptr
#include <iostream>
#include <stdio.h> using namespace std; int f(void* ptr) {
return ;
} int f(int num) {
return ;
} int main() {
int result1 = f();
//int result2 = f(NULL);
int result3 = f(nullptr);
cout << "result1 = " << result1 << endl;
//cout << "result2 = " << result2 << endl;
cout << "result3 = " << result3 << endl;
return ;
}

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

    

    最后运行的结果如下:

    

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

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

    文章推荐:

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

【C++】朝花夕拾——表达式树的更多相关文章

  1. 再讲IQueryable<T>,揭开表达式树的神秘面纱

    接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...

  2. [C#] C# 知识回顾 - 表达式树 Expression Trees

    C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...

  3. 轻量级表达式树解析框架Faller

    有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...

  4. 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...

  5. LinqToDB 源码分析——处理表达式树

    处理表达式树可以说是所有要实现Linq To SQL的重点,同时他也是难点.笔者看完作者在LinqToDB框架里面对于这一部分的设计之后,心里有一点不知所然.由于很多代码没有文字注解.所以笔者只能接合 ...

  6. LinqToDB 源码分析——生成表达式树

    当我们知道了Linq查询要用到的数据库信息之后.接下就是生成对应的表达式树.在前面的章节里面笔者就已经介绍过.生成表达式树是事实离不开IQueryable<T>接口.而处理表达式树离不开I ...

  7. 干货!表达式树解析"框架"(1)

    最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 关于我和表达式树 其实我也没有深入了解表达式树一些内在实现的原理 ...

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

    最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 为了过个好年,我还是赶快把这篇完成了吧 声明 本文内容需要有一定 ...

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

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

随机推荐

  1. SQL外键的作用

    貌似很有用,但没有真正用过: SQL的主键和外键的作用: 外键取值规则:空值或参照的主键值. (1)插入非空值时,如果主键表中没有这个值,则不能插入. (2)更新时,不能改为主键表中没有的值. (3) ...

  2. mac下破解apk文件以及apktool的相关使用

    Android apktool是一个用来处理APK文件的工具,可以对APK进行反编译生成程序的源代码和图片.XML配置.语言资源等文件,也可以添加新的功能到APK文件中.用该工具来汉化Android软 ...

  3. POJ3159 Candies —— 差分约束 spfa

    题目链接:http://poj.org/problem?id=3159 Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submiss ...

  4. idea把项目提交到svn服务器步骤

    1.设置忽略文件.文件夹 2.找到以下选项 3.选择要上传项目的svn服务器地方和svn管理目录 4.填完相关提交信息,点击share就ok啦

  5. Watir: Get document detail information in Watir.

    ie.#{element}(:id,"foo").document.currentstyle.attributeAsCamelCase so ie.#{element}(:id,& ...

  6. 从free到page cache

    Free 我们经常用free查看服务器的内存使用情况,而free中的输出却有些让人困惑,如下:   图1-1 先看看各个数字的意义以及如何计算得到: free命令输出的第二行(Mem):这行分别显示了 ...

  7. [OS][FS]查看ext3文件系统分区的superblock

    本文将介绍怎样读取一个分区的superblock: 1. 首先我们查看一下在磁盘上有哪些分区,通过fdisk -l 这里有三个分区,我们下面查看/dev/sda3(这是一个device file) 2 ...

  8. ASP.NET Core MVC 打造一个简单的图书馆管理系统 (修正版)(四)图书信息的增删改查

    前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/asp ...

  9. Python Flask 实现移动端应用接口(API)

    引言 目前,Web 应用已形成一种趋势:业务逻辑被越来越多地移到客户端,逐渐完善为一种称为富互联网应用(RIA,rich Internet application)的架构.在 RIA 中,服务器的主要 ...

  10. PowerDesigner在PDM转换为sql脚本时报错Generation aborted due to errors detected during the verification of the mod

    在设计概念数据模型(CDM)之后,转换为物理数据模型(PDM),之后转换为sql脚本时报错Generation aborted due to errors detected during the ve ...