题目:
功能设计:
- 读取用户输入的表达式创建表达式树功能
- 遍历表达式树进行表达式求值功能
- 输出表达式计算结果功能
功能实现:
1.
2.
3.
运行结果:
用户输入1,输入要计算的表达式并以#结尾,系统便会给出计算结果。
用户输入2,退出程序。
完整代码展示:
#include<iostream>
using namespace std;
//二叉树结构
typedef struct BiTNode
{
char data;
int num;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
//栈结构
typedef struct StackNode
{
BiTNode* root;
char op;
struct StackNode* next;
} StackNode, * LinkStack;
int InitStack(LinkStack& S) //构造空栈
{
S = NULL;
return 1;
}
int Push_root(LinkStack& S, BiTree e) //根节点入栈
{
LinkStack p = new StackNode;
if (!p)
exit(OVERFLOW);
p->root = e;
p->next = S;
S = p;
return 1;
}
void Push_op(LinkStack& S, char e) //操作符入栈
{
LinkStack p = new StackNode;
if (!p)
exit(OVERFLOW);
p->op = e;
p->next = S;
S = p;
}
int Pop_root(LinkStack& S, BiTree& e) //根节点出栈
{
if (S == NULL)
{
cout << "输入格式错误,请输入整数表达式";
return 0;
}
e = S->root;
LinkStack p = S;
S = S->next;
delete p;
return 1;
}
int Pop_op(LinkStack& S, char& e) //操作符出栈
{
if (S == NULL)
{
cout << "输入格式错误,请输入整数表达式";
return 0;
}
e = S->op;
LinkStack p = S;
S = S->next;
delete p;
return 1;
}
char GetTop_op(LinkStack S) //返回栈顶元素
{
if (S != NULL) //栈非空
return S->op;
}
char Precede(char t1, char t2) //判断两个运算符的优先关系
{
char f{};
switch (t2)
{
case '+':
if ((t1 == '(') || (t1 == '#'))
f = '<';
else f = '>';
break;
case '-':
if ((t1 == '(') || (t1 == '#'))
f = '<';
else f = '>';
break;
case '*':
if ((t1 == '*') || (t1 == '/') || (t1 == ')'))
f = '>';
else f = '<';
break;
case '/':
if ((t1 == '*') || (t1 == '/') || (t1 == ')'))
f = '>';
else f = '<';
break;
case '(':
f = '<';
break;
case ')':
if ((t1 == '('))
f = '=';
else f = '>';
break;
case '#':
if (t1 == '#')
f = '=';
else f = '>';
break;
}
return f;
}
int In(char i) //判断读取到的字符是否是操作符
{
switch (i)
{
case '+': case '-': case '*': case '/':
case '(': case ')': case '#': return 1;
break;
default: return 0;
}
}
int GetValue(int a, char theta, int b)
{
switch (theta)
{
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
}
void CreateExpressTree_op(BiTree& T, BiTree a, BiTree b, char theta)
//创建一棵树,左孩子是a,右孩子是b,数据域是theta用来储存运算符
{
BiTree L = new BiTNode;
L->data = theta;
L->lchild = a;
L->rchild = b;
T = L;
}
void CreateExpressTree_num(BiTree& T, BiTree a, BiTree b, int theta)
//创建一棵树,左孩子是a,右孩子是b,数据域是theta用来储存数字
{
BiTree L = new BiTNode;
L->num = theta;
L->lchild = a;
L->rchild = b;
T = L;
}
void CreateBiTree(BiTree& T) //读取输入表达式创建二叉树
{
LinkStack EXPT;
LinkStack OPTR;
InitStack(EXPT);
InitStack(OPTR);
Push_op(OPTR, '#');
BiTree a = NULL, b = NULL, c, d;
char ch, theta, f;
int m = 0;
cin >> ch;
while ((ch != '#') || (GetTop_op(OPTR)) != '#')
{
if (!In(ch)) //判断读取到的字符是不是运算符
{ //当字符是数字时
while (!In(ch))
{
//实现多位整数
ch = ch - '0';
m = m * 10 + ch;
ch = getchar();
}
if (m != 0)
{
CreateExpressTree_num(T, a, b, m); //以m为节点创建一棵只有根节点的二叉树
Push_root(EXPT, T); //将二叉树根节点T进EXPT栈
m = 0;
}
}
else //读取到的字符是四则运算符
{
switch (Precede(GetTop_op(OPTR), ch)) //判断优先级
{
case '<': Push_op(OPTR, ch); //当前字符压入OPTR栈,读取下一字符
ch = getchar();
break;
case '>': Pop_op(OPTR, theta); //弹出OPTR栈顶的运算符
Pop_root(EXPT, c); //弹出EXPT栈顶的两个操作数
Pop_root(EXPT, d);
CreateExpressTree_op(T, d, c, theta);//以theta为根,d为左子树,d为右子树,创建一棵二叉树
Push_root(EXPT, T); //使二叉树根节点进EXPT栈
break;
case '=':
Pop_op(OPTR, f);
ch = getchar();
break;
}
}
}
}
int EvaluateExPTree(BiTree T) //遍历表达式数进行表达式求值
{
int lvalue = 0, rvalue = 0;//初始值为0
if (T->lchild == NULL && T->rchild == NULL)
//如果节点为操作数,则返回该结点的数值
{
return T->num;
}
else
{
lvalue = EvaluateExPTree(T->lchild);
//递归计算左子树的值
rvalue = EvaluateExPTree(T->rchild);
//递归计算右子树的值
return GetValue(lvalue, T->data, rvalue);
//根据当前节点运算符的类型进行相应运算
}
}
int main()
{
while (true) {
cout << "******************************************" << endl;
cout << "** **" << endl;
cout << "**-----------欢迎来到表达式计算*--------**" << endl;
cout << "** **" << endl;
cout << "** 1.输入整数表达式(以#结尾): **" << endl;
cout << "** **" << endl;
cout << "** 2.退出 **" << endl;
cout << "** **" << endl;
cout << "******************************************" << endl;
int op;
cout << "请输入你的选择:";
cin >> op;
BiTree T;
switch (op) {
case 1:
cout << "请输入整数表达式(以#结尾):" << endl;
CreateBiTree(T); //创建表达式二叉树函数
cout << "计算结果为:" << EvaluateExPTree(T) << endl;
break;
case 2:
exit(0);
break;
}
}
return 0;
}