用c语言数据结构实现计算表达式为(5-4)*4-2+1,首行输入一个数字,表示运算命令的总个数,其余每行表示一个运算命令:包括运算操作符和操作数。运算操作符有只有Add、Sub、Mul,即加法、减法、乘法三种。并给出详细注释
时间: 2024-05-27 09:14:17 浏览: 84
数据结构c语言版.docx
#include <stdio.h>
#include <stdlib.h>
// 定义操作符枚举类型
typedef enum {
Add, Sub, Mul
} Operator;
// 定义操作数结构体
typedef struct {
int value; // 操作数的值
int is_operand; // 是否是操作数
} Operand;
// 定义表达式节点结构体
typedef struct ExpressionNode {
Operand operand; // 操作数
Operator operator; // 操作符
struct ExpressionNode *left; // 左子节点
struct ExpressionNode *right; // 右子节点
} ExpressionNode;
// 创建操作数节点
ExpressionNode* create_operand_node(int value) {
ExpressionNode *node = (ExpressionNode*)malloc(sizeof(ExpressionNode));
node->operand.value = value;
node->operand.is_operand = 1;
node->operator = Add; // 默认为加法
node->left = NULL;
node->right = NULL;
return node;
}
// 创建操作符节点
ExpressionNode* create_operator_node(Operator op) {
ExpressionNode *node = (ExpressionNode*)malloc(sizeof(ExpressionNode));
node->operand.is_operand = 0;
node->operator = op;
node->left = NULL;
node->right = NULL;
return node;
}
// 根据字符串获取操作符
Operator get_operator(char *op_str) {
if (op_str[0] == '+') {
return Add;
} else if (op_str[0] == '-') {
return Sub;
} else if (op_str[0] == '*') {
return Mul;
} else {
printf("Invalid operator %s\n", op_str);
exit(1);
}
}
// 根据字符串获取操作数
Operand get_operand(char *op_str) {
Operand operand;
operand.is_operand = 1;
operand.value = atoi(op_str);
return operand;
}
// 递归释放表达式节点
void free_expression_tree(ExpressionNode *root) {
if (root == NULL) {
return;
}
free_expression_tree(root->left);
free_expression_tree(root->right);
free(root);
}
// 构建表达式树
ExpressionNode* build_expression_tree(char *ops[], int n) {
ExpressionNode *root = NULL;
ExpressionNode *cur = NULL;
int i;
for (i = 0; i < n; i++) {
char *op_str = ops[i];
if (cur == NULL) {
// 如果当前节点为空,说明是第一个节点
if (op_str[0] >= '0' && op_str[0] <= '9') {
// 如果是数字,创建操作数节点,并赋值给根节点
root = create_operand_node(atoi(op_str));
} else {
// 如果是操作符,创建操作符节点,并赋值给根节点
root = create_operator_node(get_operator(op_str));
}
cur = root;
} else {
// 如果当前节点不为空,说明已经有根节点了,需要构建子树
if (op_str[0] >= '0' && op_str[0] <= '9') {
// 如果是数字,创建操作数节点,并赋值给左子节点或右子节点
ExpressionNode *node = create_operand_node(atoi(op_str));
if (cur->left == NULL) {
cur->left = node;
} else if (cur->right == NULL) {
cur->right = node;
} else {
// 如果左右子节点都已经有值了,说明根节点和左子树都已经构建好了,需要新建一个根节点,并将当前节点设置为新根节点的左子节点
ExpressionNode *new_root = create_operator_node(get_operator(op_str));
new_root->left = cur;
cur = new_root;
}
} else {
// 如果是操作符,创建操作符节点,并赋值给当前节点的操作符
cur->operator = get_operator(op_str);
}
}
// 如果当前节点的左右子节点都不为空,则说明当前节点已经构建好了,需要将当前节点设置为父节点
if (cur->left != NULL && cur->right != NULL) {
ExpressionNode *parent = create_operator_node(Add); // 父节点默认为加法
parent->left = cur;
cur = parent;
}
}
return root;
}
// 计算表达式树的值
int evaluate_expression_tree(ExpressionNode *root) {
if (root == NULL) {
return 0;
}
if (root->operand.is_operand) {
return root->operand.value;
}
int left_val = evaluate_expression_tree(root->left);
int right_val = evaluate_expression_tree(root->right);
switch (root->operator) {
case Add:
return left_val + right_val;
case Sub:
return left_val - right_val;
case Mul:
return left_val * right_val;
default:
printf("Invalid operator\n");
exit(1);
}
}
int main() {
int n; // 运算命令的总个数
scanf("%d", &n);
int i, j;
for (i = 0; i < n; i++) {
int m; // 运算命令中操作数和操作符的总个数
scanf("%d", &m);
char *ops[m]; // 保存运算命令中的操作数和操作符
for (j = 0; j < m; j++) {
char op_str[10]; // 操作数或操作符的字符串表示
scanf("%s", op_str);
ops[j] = op_str;
}
ExpressionNode *root = build_expression_tree(ops, m);
int result = evaluate_expression_tree(root);
printf("%d\n", result);
free_expression_tree(root);
}
return 0;
}
阅读全文