表達式二叉樹順序存儲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 : [email protected]
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+-
樣例圖解
鳴謝
最後
- 由於博主水平有限,不免有疏漏之處,歡迎讀者隨時批評指正,以免造成不必要的誤解!