Expression Tree เป็น Binary Tree ที่ใช้แสดงนิพจน์ทางคณิตศาสตร์ โดยโหนดภายใน (internal nodes) เป็นตัวดำเนินการ (operators) และโหนดใบ (leaf nodes) เป็นตัวถูกดำเนินการ (operands)
อัลกอริทึมสร้างจาก Prefix
- อ่าน Prefix expression จากขวาไปซ้าย
- ถ้าเป็นตัวเลข (operand) → สร้างโหนดและ push เข้า stack
- ถ้าเป็นตัวดำเนินการ (operator) → pop 2 โหนดจาก stack, สร้างโหนดใหม่เป็น parent, push กลับเข้า stack
- สุดท้าย stack จะเหลือเพียงโหนดเดียว คือ root ของ Expression Tree
ตัวอย่างโค้ด
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
struct TreeNode {
char data;
TreeNode* left;
TreeNode* right;
TreeNode(char val) : data(val), left(nullptr), right(nullptr) {}
};
class ExpressionTree {
private:
TreeNode* root;
bool isOperator(char ch) {
return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^';
}
bool isOperand(char ch) {
return isdigit(ch) || isalpha(ch);
}
public:
ExpressionTree() : root(nullptr) {}
void buildFromPrefix(const string& prefix) {
stack<TreeNode*> st;
// อ่านจากขวาไปซ้าย
for (int i = prefix.length() - 1; i >= 0; --i) {
char ch = prefix[i];
if (isspace(ch)) continue;
if (isOperand(ch)) {
st.push(new TreeNode(ch));
} else if (isOperator(ch)) {
if (st.size() < 2) {
cerr << "Invalid prefix expression" << endl;
return;
}
TreeNode* node = new TreeNode(ch);
node->left = st.top(); st.pop();
node->right = st.top(); st.pop();
st.push(node);
}
}
if (!st.empty()) root = st.top();
}
// Traversals
void inorder(TreeNode* node) {
if (!node) return;
if (isOperator(node->data)) cout << "(";
inorder(node->left);
cout << node->data;
inorder(node->right);
if (isOperator(node->data)) cout << ")";
}
void preorder(TreeNode* node) {
if (!node) return;
cout << node->data;
preorder(node->left);
preorder(node->right);
}
void postorder(TreeNode* node) {
if (!node) return;
postorder(node->left);
postorder(node->right);
cout << node->data;
}
void printAll() {
cout << "Prefix: "; preorder(root); cout << endl;
cout << "Infix: "; inorder(root); cout << endl;
cout << "Postfix: "; postorder(root); cout << endl;
}
~ExpressionTree() {
// TODO: implement destructor to free memory
}
};
int main() {
ExpressionTree et;
string prefix;
cout << "Enter prefix expression (e.g., ++7*626): ";
cin >> prefix;
et.buildFromPrefix(prefix);
et.printAll();
return 0;
}
ผลลัพธ์ตัวอย่าง
Enter prefix expression (e.g., ++7*626): ++7*626 Prefix: ++7*626 Infix: (7+((6*2)+6)) Postfix: 762*+6+
การใช้งาน Expression Tree
- การคำนวณนิพจน์: ใช้ postorder traversal กับ stack
- การจัดรูปแบบนิพจน์: แปลงระหว่าง prefix, infix, postfix
- Compiler design: ส่วนหนึ่งของ parsing และ code generation
- Symbolic math: การ微分, integration แบบสัญลักษณ์
ขยายความสามารถ
สามารถเพิ่มรองรับ: ตัวเลขหลายหลัก, ตัวแปร, ฟังก์ชัน (sin, cos), และการประเมินค่า (evaluate) ได้