表达式二叉树顺序存储C++实现
表达式二叉树
借助二叉树结构来存储表达式,对于表达式二叉树,根节点为表达式中的运算符,子树根节点也为必然运算符,叶子节点必然为运算数,在运算符中,括号优先级最大,加减符号次之,乘除符号最小。递归地建立表达式二叉树,遇到括号则去掉,选择高优先级的运算符,以该运算符为子树根节点,左右子表达式递归地建立左右子树,直到遇到叶子节点。
int ExpressionBinaryTree::buildTree(const string& expression, int begin, int end) {
int nodeNumber;
int addSub = -1;
int mulDiv = -1;
int parentheses = 0;
if (end - begin == 1) {
// 若为叶子节点
nodeNumber = ++nodeCount;
leftChild[nodeNumber] = rightChild[nodeNumber] = 0;
nodes[nodeNumber] = expression[begin];
return nodeNumber;
}
for (int i = begin; i < end; i++) {
if (expression[i] == '(') {
parentheses++;
} else if (expression[i] == ')') {
parentheses--;
} else if ((expression[i] == '+' || expression[i] == '-') && parentheses == 0) {
// 若不存在括号,且存在加减号
addSub = i;
} else if ((expression[i] == '*' || expression[i] == '/') && parentheses == 0) {
// 若不存在括号和加减号,但存在乘除号
mulDiv = i;
}
}
int operatorNumber;
if (addSub >= 0) {
// 若存在加减号,以加号或减号为中心,左右两边的子表达式分别作为左右子树
operatorNumber = addSub;
} else if (mulDiv >= 0) {
// 若不存在加减号,但存在乘除号,以乘号或除号为中心,左右两边的子表达式分别作为左右子树
operatorNumber = mulDiv;
} else {
// 若存在括号,去掉括号,继续递归
return buildTree(expression, begin + 1, end - 1);
}
nodeNumber = ++nodeCount;//增加新节点
leftChild[nodeNumber] = buildTree(expression, begin, operatorNumber);//递归建立左子树
rightChild[nodeNumber] = buildTree(expression, operatorNumber + 1, end);//递归建立右子树
nodes[nodeNumber] = expression[operatorNumber];//将表达式中的值插入表达式二叉树
return nodeNumber;
}
实现代码
/*
author : eclipse
email : eclipsecs@qq.com
time : Thu May 14 10:55:36 2020
*/
#include<bits/stdc++.h>
using namespace std;
class ExpressionBinaryTree {
private:
static const int MAX_CAPACITY = 1024;
int leftChild[MAX_CAPACITY];
int rightChild[MAX_CAPACITY];
char nodes[MAX_CAPACITY];
int nodeCount;
int root;
string expression;
int buildTree(const string& expression, int begin, int end);
void inOrderTraverse(int p);
void preOrderTraverse(int p);
void postOrderTraverse(int p);
public:
void preOrderSequence();
void inOrderSequence();
void postOrderSequence();
ExpressionBinaryTree(string expression);
};
ExpressionBinaryTree::ExpressionBinaryTree(string expression) {
this->expression = expression;
nodeCount = 0;
for (int i = 0; i < MAX_CAPACITY; i++) {
leftChild[i] = rightChild[i] = 0;
nodes[i] = 0;
}
root = buildTree(this->expression, 0, this->expression.length());
}
int ExpressionBinaryTree::buildTree(const string& expression, int begin, int end) {
int nodeNumber;
int addSub = -1;
int mulDiv = -1;
int parentheses = 0;
if (end - begin == 1) {
nodeNumber = ++nodeCount;
leftChild[nodeNumber] = rightChild[nodeNumber] = 0;
nodes[nodeNumber] = expression[begin];
return nodeNumber;
}
for (int i = begin; i < end; i++) {
if (expression[i] == '(') {
parentheses++;
} else if (expression[i] == ')') {
parentheses--;
} else if ((expression[i] == '+' || expression[i] == '-') && parentheses == 0) {
addSub = i;
} else if ((expression[i] == '*' || expression[i] == '/') && parentheses == 0) {
mulDiv = i;
}
}
int operatorNumber;
if (addSub >= 0) {
operatorNumber = addSub;
} else if (mulDiv >= 0) {
operatorNumber = mulDiv;
} else {
return buildTree(expression, begin + 1, end - 1);
}
nodeNumber = ++nodeCount;
leftChild[nodeNumber] = buildTree(expression, begin, operatorNumber);
rightChild[nodeNumber] = buildTree(expression, operatorNumber + 1, end);
nodes[nodeNumber] = expression[operatorNumber];
return nodeNumber;
}
void ExpressionBinaryTree::preOrderTraverse(int p) {
printf("%c", nodes[p]);
if (leftChild[p]) {
preOrderTraverse(leftChild[p]);
}
if (rightChild[p]) {
preOrderTraverse(rightChild[p]);
}
}
void ExpressionBinaryTree::preOrderSequence() {
preOrderTraverse(root);
}
void ExpressionBinaryTree::inOrderTraverse(int p) {
if (leftChild[p]) {
printf("(");
inOrderTraverse(leftChild[p]);
}
printf("%c", nodes[p]);
if (rightChild[p]) {
inOrderTraverse(rightChild[p]);
printf(")");
}
}
void ExpressionBinaryTree::inOrderSequence() {
inOrderTraverse(root);
}
void ExpressionBinaryTree::postOrderTraverse(int p) {
if (leftChild[p]) {
postOrderTraverse(leftChild[p]);
}
if (rightChild[p]) {
postOrderTraverse(rightChild[p]);
}
printf("%c", nodes[p]);
}
void ExpressionBinaryTree::postOrderSequence() {
postOrderTraverse(root);
}
int main(int argc, char const *argv[])
{
string expression;
cin >> expression;
ExpressionBinaryTree *expressionBinaryTree = new ExpressionBinaryTree(expression);
printf("Pre order\n");
expressionBinaryTree->preOrderSequence();
printf("\nIn order\n");
expressionBinaryTree->inOrderSequence();
printf("\nPost order\n");
expressionBinaryTree->postOrderSequence();
return 0;
}
输入数据
a*b-((c+d*e/f)+g)
输出结果
Pre order
-*ab++c/*defg
In order
((a*b)-((c+((d*e)/f))+g))
Post order
ab*cde*f/+g+-
样例图解
鸣谢
最后
- 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解!