关于二叉树求四则运算

                                                                     
1.如图二叉树表示下述表达式,a+b*(c-d)-e/f,若先序遍历此二叉树,按访问节点的顺序将节点排列起来,可达到二叉树的先序序列为,-+a*b-cd/ef。
2.对于此篇博文,我们要解决的问题,是如何通过表达式建立这个二叉树,并判断输入的序列是否正确,求出表达式的结果。
3.解决这个问题,大致分为3个部分
  1. 将表达式进行转换成一个特定的链表,如图;
  2. 将这个链表转换为一个二叉树
  3. 求解二叉树。

 

 

 

 

 

#include<iostream>
#include<string>
#include<cctype>
using namespace std;
typedef struct Dtree
{
Dtree * lchild;
Dtree * rnchild;
char Date[12];
}PDtree;
int store(string temp, PDtree * & Shead);
int change (Dtree * & Shead);
void FreeTree(Dtree * &head);
int OperateT(Dtree * head,int & sign);
int deleteblank(string & temp);
int deal(Dtree * &head);
int liancheng(Dtree * &head);

int main()
{
int sign=1;
int value=1;
Dtree * Shead=NULL;
string oper;
cout<<"please the expression :"<<endl<<">>";
getline(cin,oper);
sign=store(oper,Shead);
if(sign==0)
{
cout<<"your input is error"<<endl;
goto end;
}
change(Shead);
value=OperateT(Shead,sign);
if(sign==2)
{
cout<<"the date you input is error"<<endl;
goto end;
}
cout<<"The value of expression is "<<value<<endl;
end:
FreeTree(Shead);
return 0;
}
int deleteblank(string & temp)
{
int i=0;
int j=0;
while(temp[i]==' '||temp[i]=='\t')
temp.erase(0,1);
j=temp.size()-1;
while(j>0&&(temp[j]==' '||temp[j]=='\t'))
{
temp.erase(j-1,1);
j=temp.size()-1;
}
temp.assign(temp.begin()+i,temp.end());
return 0;
}
int store(string temp,Dtree * & Shead)
{
int countdata=0;
int countop=0;
deleteblank(temp);
int length=temp.size();
while(length!=0&&temp[0]=='('&&temp[length-1]==')')
{
temp.assign(&temp[1],length-2);
deleteblank(temp);
length=temp.size();
}
if(length==0)
{
Shead=NULL;
return 0;
}
Shead=new Dtree;
Shead->lchild=NULL;
Shead->rnchild=NULL;
Dtree *temptree=Shead;
for(int i=0;i<length;)
{
if(temp[i]=='(')
{
++countdata;
if(countdata-countop!=1)
return 0;

++i;
int sign1=i;
int count=1;
while(i<length&&count!=0)
{
if(temp[i]=='(') ++count;
else if(temp[i]==')') --count;
++i;
if(count<0)
return 0;
}
if(count!=0)
return 0;
string temp2(temp,sign1,i-sign1-1);
deleteblank(temp2);
if(temp2.size()==0)
return 0;
sign1=store(temp2,temptree->lchild);
if(sign1==0)
return 0;
temptree->Date[0]=0;
}
else if(temp[i]==')')
return 0 ;
else if(isdigit(temp[i]))
{
++countdata;
if(countdata-countop!=1)
return 0;
int count=0;
while(i<length&&isdigit(temp[i])&&count<11)
{
temptree->Date[count]=temp[i];
++i;
++count;
}
temptree->Date[count]=0;
}
else if(temp[i]=='+'||temp[i]=='-'||temp[i]=='/'||temp[i]=='*')
{
++countop;
if(countop!=countdata)
return 0;
temptree->Date[0]=temp[i];
++i;
temptree->Date[1]=0;
}
else
return 0;
while((i<length)&&(temp[i]==' '||temp[i]=='\t'))
++i;
if(i==length) return 1;
else
{
temptree->rnchild=new Dtree;
temptree=temptree->rnchild;
temptree->lchild=NULL;
temptree->rnchild=NULL;
}
}
}
int change(Dtree * & Shead)
{
if(Shead->rnchild==NULL)
{
deal(Shead);
return 1;
}
Dtree * start=Shead;
Dtree * temp3=Shead;
Dtree * temp2=temp3->rnchild;
Dtree * temp1=temp2->rnchild;
int sign=0;
while(temp1)
{
if(temp2->Date[0]=='+'||temp2->Date[0]=='-')
{
temp3->rnchild=NULL;
liancheng(start);
if(sign==0)
{
sign=1;
Shead=temp2;
Shead->lchild=start;
}
else
{
Shead->rnchild=start;
temp3=Shead;
Shead=temp2;
Shead->lchild=temp3;
}
start=temp1;
temp3=temp1;
temp2=temp1->rnchild;
if(temp2==NULL)
break;
temp1=temp2->rnchild;
continue;
}
temp3=temp3->rnchild;
temp2=temp2->rnchild;
temp1=temp1->rnchild;
}
liancheng(start);
if(sign==0)
Shead=start;
else
Shead->rnchild=start;
return 1;
}
int deal(Dtree * & head)
{
if(head->Date[0]==0)
{
head=head->lchild;
change(head);
return 0;
}
else
{
head->lchild=NULL;
head->rnchild=NULL;
}
return 1;
}
//sign as a sign ,if sign==2,*/, if sign=1 ,+-,, if sign=0, head
int liancheng(Dtree * &head)
{
if(head->rnchild==NULL)
{
deal(head);
return 0;
}
Dtree *temp2=NULL;
Dtree * temp=head;
head=head->rnchild;
head->lchild=temp;
temp=head->rnchild->rnchild;
deal(head->lchild);
deal(head->rnchild);

while(temp)
{
temp2=head;
head=temp;
temp=temp->rnchild->rnchild;
head->lchild=temp2;
deal(head->rnchild);
}
return 1;
}
void FreeTree(Dtree * &head)
{
if(head==NULL) return;
else
{
FreeTree(head->lchild);
FreeTree(head->rnchild);
delete(head);
head=NULL;
}
}
int OperateT(Dtree * head,int & sign)
{
int left=0;
int right=0;
int value=1;
if(head->lchild==NULL)
return atoi(head->Date);
left=OperateT(head->lchild, sign);
if(sign==2) return 0;
right=OperateT(head->rnchild, sign);
if(sign==2) return 0;
if(head->Date[0]=='/'&&right==0)
{
sign=2;
return 0;
}
switch(head->Date[0])
{
case '+':
value=left+right;
break;
case '-':
value=left-right;
break;
case '*':
value=left*right;
break;
case '/':
value=left/right;
break;
default:
value=0;
}
return value;
}

转载于:https://www.cnblogs.com/firstguo/archive/2013/04/08/3006551.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于使用C++实现二叉树来解决四则运算的问题,可以使用递归的方式来构建二叉树,并通过遍历二叉树进行四则运算的计算。 首先,定义一个二叉树节点类,包含操作符和操作数两个成员变量: ```cpp class TreeNode { public: char op; // 操作符 int val; // 操作数 TreeNode* left; // 左子节点 TreeNode* right; // 右子节点 }; ``` 然后,构建二叉树的函数可以通过递归的方式实现,根据四则运算表达式的特点,可以选择从右向左构建二叉树。例如,对于表达式 "3 + 4 * 5",可以先构建一个节点表示乘法,然后将其右子节点设置为4,左子节点递归构建。 ```cpp TreeNode* buildTree(string expr) { int n = expr.size(); if (n == 0) { return nullptr; } TreeNode* root = new TreeNode(); int idx = -1; // 记录操作符位置 // 从右向左找到第一个加减法操作符的位置 for (int i = n - 1; i >= 0; i--) { if (expr[i] == '+' || expr[i] == '-') { idx = i; break; } } // 如果找到了加减法操作符,将其作为根节点 if (idx != -1) { root->op = expr[idx]; root->left = buildTree(expr.substr(0, idx)); root->right = buildTree(expr.substr(idx + 1)); return root; } // 如果没有找到加减法操作符,再找乘除法操作符 for (int i = n - 1; i >= 0; i--) { if (expr[i] == '*' || expr[i] == '/') { idx = i; break; } } // 如果找到了乘除法操作符,将其作为根节点 if (idx != -1) { root->op = expr[idx]; root->left = buildTree(expr.substr(0, idx)); root->right = buildTree(expr.substr(idx + 1)); return root; } // 如果没有找到操作符,说明是一个操作数,将其存入节点的val中 root->op = '#'; root->val = stoi(expr); return root; } ``` 最后,通过遍历二叉树来计算四则运算的结果,可以使用递归的方式实现: ```cpp int evaluateTree(TreeNode* root) { if (root->op == '#') { return root->val; } int leftVal = evaluateTree(root->left); int rightVal = evaluateTree(root->right); if (root->op == '+') { return leftVal + rightVal; } else if (root->op == '-') { return leftVal - rightVal; } else if (root->op == '*') { return leftVal * rightVal; } else if (root->op == '/') { return leftVal / rightVal; } return 0; } ``` 使用示例: ```cpp string expr = "3+4*5"; TreeNode* root = buildTree(expr); int result = evaluateTree(root); cout << "Result: " << result << endl; // 输出 23 ``` 通过以上的代码,可以使用二叉树来解决简单的四则运算问题。当然,对于复杂的表达式,可能需要更多的代码来处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值