【C++】朝花夕拾——表达式树
表达式树:
叶子是操作数,其余结点为操作符,是二叉树的其中一种应用
====================我是分割线======================
一棵表达式树如下图:

若是对它做中序遍历,则可以得到中缀表达式
做后序遍历,则可以得到后缀表达式
已知树的结点可以表示成:
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++】朝花夕拾——表达式树的更多相关文章
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- 轻量级表达式树解析框架Faller
有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...
- 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树
这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...
- LinqToDB 源码分析——处理表达式树
处理表达式树可以说是所有要实现Linq To SQL的重点,同时他也是难点.笔者看完作者在LinqToDB框架里面对于这一部分的设计之后,心里有一点不知所然.由于很多代码没有文字注解.所以笔者只能接合 ...
- LinqToDB 源码分析——生成表达式树
当我们知道了Linq查询要用到的数据库信息之后.接下就是生成对应的表达式树.在前面的章节里面笔者就已经介绍过.生成表达式树是事实离不开IQueryable<T>接口.而处理表达式树离不开I ...
- 干货!表达式树解析"框架"(1)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 关于我和表达式树 其实我也没有深入了解表达式树一些内在实现的原理 ...
- 干货!表达式树解析"框架"(2)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 为了过个好年,我还是赶快把这篇完成了吧 声明 本文内容需要有一定 ...
- 干货!表达式树解析"框架"(3)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 这应该是年前最后一篇了,接下来的时间就要陪陪老婆孩子了 关于表达 ...
随机推荐
- how to create modals with Bootstrap
In this tutorial you will learn how to create modals with Bootstrap. Creating Modals with Bootstrap ...
- POJ3189 Steady Cow Assignment —— 二分图多重匹配/最大流 + 二分
题目链接:https://vjudge.net/problem/POJ-3189 Steady Cow Assignment Time Limit: 1000MS Memory Limit: 65 ...
- 调整多个控件的dock的顺序
https://stackoverflow.com/questions/2607508/how-to-control-docking-order-in-winforms Go to View -> ...
- 深度学习 dns tunnel检测 使用统计特征 全连接网络——精度99.8%
代码如下: import numpy as np import tflearn from tflearn.layers.core import dropout from tflearn.layers. ...
- linux 忘记root(这里以centos 6.5为例)密码的解决办法
在使用linux的过程中有时候会忘记root用户的密码(尤其是进行交接而文档内容不全的时候),这个时候我们就可以进入单用户模式来重置root用户密码.下面来讲解重置root密码的方式,也可以说是破解r ...
- Unity3d 应用系统分析
- 景女神与她的托福(BFS+状压)
景女神与她的托福 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submis ...
- WCF、WebAPI、WebService之间的区别
Web Service 1.它是基于SOAP协议的,数据格式是XML 2.只支持HTTP协议 3.它不是开源的,但可以被任意一个了解XML的人使用 4.它只能部署在IIS上 WCF 1.这个也是基于S ...
- Luogu P1462 通往奥格瑞玛的道路【二分/最短路】
题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛 题目描述 在艾泽拉斯, ...
- [PKUWC2018]猎人杀
题解 感觉是一道神题,想不出来 问最后\(1\)号猎人存活的概率 发现根本没法记录状态 每次转移的分母也都不一样 可以考虑这样一件事情: 如果一个人被打中了 那么不急于从所有人中将ta删除,而是给ta ...