这篇借鉴别人的思想编的程序,c和c++结合,将就着看吧
原文http://blog.csdn.net/qq120848369/article/details/5673969
思路:eg:(5+(7-4)*3+6/2)
画成二叉树如图:(别画错,有的人把5那个+给画成根节点,自己按正确的数学思路计算一遍就知道为什么这样画)
代码的核心思想是:找到表达式中最后使用的操作符,作为二叉树根节点,左侧右侧递归生成的二叉树分别为左孩子和右孩子
那关键是:找表达式中最后使用的操作符
算数表达式的计算顺序: 先括号 先乘除 后加减 加减运算以及乘除运算都是从左到右
所以最后计算是括号外面的最右边的+、-
当然 括号外面没有+、- 才可以找最右边的*、/
如果括号外面没有这四个操作符,那就说明整个式子被包含在一个括号中,去掉括号就可以继续找了
在判断操作符是否在括号里面时,这里设定一个flag=0遇到左括号+1 ,遇到右括号-1
那么flag=0证明在括号外面
程序也有注释 ,应该没那么难懂
#include <iostream>
#define MAXSIZE 1000
using namespace std;
//二叉树结点结构体定义
typedef struct BtreeNode{
char data;
struct BtreeNode *lchild;
struct BtreeNode *rchild;
}BtreeNode;
//算术表达式转化二叉树
/*
afa为指向表达式字符串的指针
s为要转化的表达式字符串的起始位置
e为要转化的表达式字符串的结束位置的后一个
*/
BtreeNode* afaToBtree(char *afa,int s,int e){
//如果只有一个数那就是叶子结点了
if(e-s==1)
{
BtreeNode* bn=(struct BtreeNode*)malloc(sizeof(struct BtreeNode));
bn->data=afa[s];
bn->lchild=NULL;
bn->rchild=NULL;
return bn;
}
/*
local_r记录当前要转化的表达式生成二叉树的根节点操作符的位置
flag记录是否当前搜索在括号里面
m_m_p记录当前表达式中括号外面最右边的+、-位置
a_s_p记录当前表达式中括号外面最右边的*、/位置
*/
int local_r=0,flag=0;
int m_m_p=0,a_s_p=0;
for(int i=s;i<e;i++)
{
if(afa[i]=='(')flag++;
else if(afa[i]==')')flag--;
if(flag==0){
if(afa[i]=='*'||afa[i]=='/')
m_m_p=i;
else if(afa[i]=='+'||afa[i]=='-')
a_s_p=i;
}
}
if((m_m_p==0)&&(a_s_p==0))
//如果式子整个有括号如(5-2*3+7),即括号外面没有操作符,则去掉括号找二叉树
afaToBtree(afa,s+1,e-1);
else
{
//如果有+或者-,则根节点为最右边的+或-,否则是最右边的*或/
if(a_s_p>0)local_r=a_s_p;
else if(m_m_p>0)local_r=m_m_p;
//确定根节点和根节点的左孩子和右孩子
BtreeNode* b=(struct BtreeNode*)malloc(sizeof(struct BtreeNode));;
b->data=afa[local_r];
b->lchild=afaToBtree(afa,s,local_r);
b->rchild=afaToBtree(afa,local_r+1,e);
return b;
}
}
void main(){
char input[MAXSIZE];
int len=0;
//初始化
memset(input,'\0',sizeof(input));
cin >> input ;
BtreeNode* myBtree=(struct BtreeNode*)malloc(sizeof(struct BtreeNode));
//myBtree就是input算术表达式产生的二叉树的根节点(指针类型哦)
myBtree=afaToBtree(input,0,strlen(input));
//你可以对生成的二叉树进行操作 如求值,先序输出(自己编函数吧)
}