树和二叉树实现简单计算器
运用二叉树的知识进行表达式的求值运算
比如题目:实现一个简单的计算器。通过键盘输入一个包含圆括号、加减乘除等符号组成的算术表达式字符串,输出该算术表达式的值。
要求:
- 系统至少能实现加、减、乘、除等运算;
- 利用二叉树算法思想求解表达式的值,先构造由表达式构成的二叉树,然后再利用通过对二叉树进行前后序遍历。
- 求解算术表达式的值。
代码实现如下
构建结构体如下:
#include<stdio.h>
#include<stdlib.h>
typedef struct BiTrNode {
char data;//存放数据
struct BiTrNode *lchild;//左
struct BiTrNode *rchild;//右
} BiTrNode,*BiTree;
构建二叉树:利用两个栈,一个符号栈,一个结点指针栈,利用栈来构建二叉树
void createTree(BiTree &T,char *str) {
char oper[10];//符号栈
BiTree *stack=(BiTree*)malloc(sizeof(BiTree)*10);;//存放二叉树结点的栈
int top1=0,top2=0;//top1符号栈的指针,top2是结点栈指针
int i=0;
char e;
while(str[i]!='\0') {
if(str[i]>='0'&&str[i]<='9') { //数字直接压入结点栈中
T=new BiTrNode;//生成根节点
T->data=str[i];
T->lchild=NULL;
T->rchild=NULL;
stack[top2]=T;
top2++;
T=NULL;
} else {
/*加减 */
if(str[i]=='+'||str[i]=='-') {
if(top1==0) {
oper[top1]=str[i];//符号入栈
top1++;
} else {
//出栈操作
do {
top1--;
e=oper[top1];
oper[top1]=NULL;//出栈
if(e=='(') {
oper[top1]=e;//符号入栈
top1++;
} else {
//符号出栈
//建立树
T=new BiTrNode;//生成根节点
T->data=e;
T->rchild=stack[top2-1];
T->lchild=stack[top2-2];
stack[top2-2]=T;
stack[top2--]=NULL;
}
} while(top1!=0&&e!='(');
//入栈操作
oper[top1]=str[i];
top1++;
}
}
else if(str[i]==')') {
do {
//出栈
top1--;
e=oper[top1];
oper[top1]=NULL;
//建立树并入stack栈,除了最后一个'('
if(e!='(') {
T=new BiTrNode;//生成根节点
T->data=e;
T->rchild=stack[top2-1];
T->lchild=stack[top2-2];
stack[top2-2]=T;
stack[top2--]=NULL;
}
} while(e!='(');
}
/*左括号 */
else if(str[i]=='('){
oper[top1]=str[i];
top1++;
}
/*乘除 */
else if(str[i]=='*'||str[i]=='/'){
if(oper[top1-1]=='+'||oper[top1-1]=='-'||oper[top1-1]=='('||top1==0) {
oper[top1]=str[i];
top1++;
}else{
//先将oper的顶元素出栈
top1--;
e=oper[top1];
oper[top1]=NULL;
//创建树
T=new BiTrNode;//生成根节点
T->data=e;
T->rchild=stack[top2-1];
T->lchild=stack[top2-2];
stack[top2-2]=T;
stack[top2--]=NULL;
//再入栈
oper[top1]=str[i];
top1++;
}
}
else if(str[i]=='\0') break;
}
i++;
}
//清空栈
while(top1!=0){
//先将oper的顶元素出栈
top1--;
e=oper[top1];
oper[top1]=NULL;
//创建树
T=new BiTrNode;//生成根节点
T->data=e;
T->rchild=stack[top2-1];
T->lchild=stack[top2-2];
stack[top2-2]=T;
stack[top2--]=NULL;
}
T=stack[0];
}
采用后序遍历二叉树:
//后序遍历二叉树
void PrintBiTree(BiTree T){
if(T){
PrintBiTree(T->lchild);
PrintBiTree(T->rchild);
printf("%c",T->data);
}
}
前序遍历:
//前序遍历二叉树
void PrintBiTree2(BiTree T){
if(T){
printf("%c",T->data);
PrintBiTree(T->lchild);
PrintBiTree(T->rchild);
}
}
对表达式进行计算(返回int):
//计算表达式
int Count(BiTree T)
{
int a,b;
if(T)
{
a=Count(T->lchild);//计算左树
b=Count(T->rchild);//计算右树
switch(T->data)//处理
{
case'+':return a+b;
case'-':return a-b;
case'*':return a*b;
case'/':
if(b!=0)return a/b;
else printf("分母为0");exit(0);
default:return T->data-'0';//递归出口
}
}
}
以上便是通过构建二叉树的方法实现简单的计算器功能的方法,重点是将表达式构建成二叉树的形式。最后写一个main方法跑一下;
int main(){
char str[10];
printf("请输入计算表达式:") ;
gets(str);
BiTree T;
createTree(T,str);
printf("后缀表达式:") ;
PrintBiTree(T);
printf("\n前缀表达式:") ;
PrintBiTree2(T);
printf("\n计算结果为:") ;
printf("%d",Count(T));
return 0;
}
测试的结果入下: