二叉树计算中缀表达式,支持指数运算符“^”,支持括号,以字符串形式输入。括号通过递归处理。下一步要支持科学计数,处理空格正负号,检查输入错误。
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#define BRACKETSMARK 0x40
#define MAXBUFFERLEN 1024
typedef struct tagbintree
{
char op;
char mark;
double fvalue;
struct tagbintree *lchild;
struct tagbintree *rchild;
}bintree;
char getlevel(char op);
int isop(char c);
double caltree(const bintree *node);
void preorderdistree(const bintree *node);
void postorderdistree(const bintree *node);
void destorytree(bintree **node);
void appendnode(bintree **node, char op, double value);
bintree *createtree_(const char **szexpress);
bintree *createtree(const char *szexpress);
int main(void)
{
char s[1024];
bintree *root;
root = createtree("12*15");
postorderdistree(root);
printf("\n=%lf\n\n", caltree(root));
destorytree(&root);
root = createtree("-12+390.564*56*78-90/18.56*129.35+86.073+1345.302+10.9301*99.01");
postorderdistree(root);
printf("\n=%lf\n", caltree(root));
destorytree(&root);
strcpy(s, "1+2*3*2^0.5*3^0.3-6");
printf("\n%s\n", s);
root = createtree(s);
postorderdistree(root);
printf("\n=%lf\n\n", caltree(root));
destorytree(&root);
strcpy(s, "((((-(11.86)-2)+54.89*45.8+56+54+5)*2)*(12.39+23*2^0.81))*2+2^3^0.3");
printf("%s\n", s);
root = createtree(s);
postorderdistree(root);
printf("\n=%lf", caltree(root));
destorytree(&root);
getch();
}
void preorderdistree(const bintree *node)
{
if (node != NULL)
{
if (node->op != 0)
printf("%c ", node->op);
else
printf("%f ", node->fvalue);
preorderdistree(node->lchild);
preorderdistree(node->rchild);
}
}
void postorderdistree(const bintree *node)
{
if (node != NULL)
{
postorderdistree(node->lchild);
postorderdistree(node->rchild);
if (node->op != 0)
printf("%c ", node->op);
else
printf("%f ", node->fvalue);
}
}
void destorytree(bintree **node)
{
if (*node == NULL)
return;
if ((*node)->lchild != NULL)
destorytree(&(*node)->lchild);
if ((*node)->rchild != NULL)
destorytree(&(*node)->rchild);
free(*node);
*node = NULL;
}
void appendnode(bintree **node, char op, double value)
{
bintree *node1;
bintree *node2;
node1 = (bintree *)malloc(sizeof(bintree));
node1->op = op;
node1->mark = 0;
node2 = (bintree *)malloc(sizeof(bintree));
node2->op = 0;
node2->fvalue = value;
node2->mark = 0;
node2->lchild = NULL;
node2->rchild = NULL;
node1->rchild = node2;
if (getlevel((*node)->op) != 0 && getlevel(node1->op) > getlevel((*node)->op) && ((*node)->mark & BRACKETSMARK) != BRACKETSMARK)
{
bintree *rp = *node;
while(getlevel(rp->rchild->op) != 0 && getlevel(node1->op) > getlevel(rp->rchild->op) && (rp->rchild->mark & BRACKETSMARK) != BRACKETSMARK)
{
rp = rp->rchild;
}
node1->lchild = rp->rchild;
rp->rchild = node1;
}
else
{
node1->lchild = *node;
*node = node1;
}
}
char getlevel(char op)
{
if (op == 0)
return 0;
if (op == '^')
return 3;
if (op == '*' || op == '/')
return 2;
if (op == '+' || op == '-')
return 1;
}
int isop(char c)
{
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '(' || c == ')')
return 1;
return 0;
}
double caltree(const bintree *node)
{
if (node->op == 0)
return node->fvalue;
if (node->op == '^')
return pow(caltree(node->lchild), caltree(node->rchild));
if (node->op == '*')
return caltree(node->lchild) * caltree(node->rchild);
if (node->op == '/')
return caltree(node->lchild) / caltree(node->rchild);
if (node->op == '+')
return caltree(node->lchild) + caltree(node->rchild);
if (node->op == '-')
return caltree(node->lchild) - caltree(node->rchild);
}
bintree *createtree_(const char **szexpress)
{
const char **ptr = szexpress;
char op = 0;
char sign = 0; /* 符号位:无符号--0,'-'--sign = 1 - sign;,'+'--直接略过 */
char numstr[MAXBUFFERLEN] = {"0"};
char *ptrnum = numstr;
bintree *root;
if (*szexpress == NULL)
return NULL;
while(**ptr == ' ') /* 前导空格 */
{
(*ptr)++;
}
if (**ptr == '+') /* 前导'+' */
{
(*ptr)++;
}
if (**ptr == '(')
{
(*ptr)++;
root = createtree_(ptr);
}
else
{
root = (bintree *)malloc(sizeof(bintree));
if (**ptr == '-')
{
root->op = 0;
root->fvalue = 0;
root->mark = 0;
root->lchild = NULL;
root->rchild = NULL;
}
else
{
while(**ptr)
{
if (isop(**ptr))
break;
*ptrnum++ = **ptr;
(*ptr)++;
}
*ptrnum = '\0';
root->op = 0;
root->fvalue = atof(numstr); /* numstr 可能是函数名, numstr = ""输入错误 */
root->mark = 0;
root->lchild = NULL;
root->rchild = NULL;
}
}
if (**ptr == ')')
{
(*ptr)++;
root->mark |= BRACKETSMARK;
return root;
}
if (**ptr != '\0')
{
op = **ptr;
(*ptr)++;
ptrnum = numstr;
while(**ptr)
{
if (isop(**ptr))
{
if (**ptr == '(')
{
bintree *subexprtree = (bintree *)malloc(sizeof(bintree));
subexprtree->op = op;
subexprtree->mark = 0;
(*ptr)++;
*ptrnum = '\0'; /* if (ptrnum != numstr) 此处就是函数,numstr是函数名 */
subexprtree->rchild = createtree_(ptr);
if (getlevel(root->op) != 0 && getlevel(subexprtree->op) > getlevel(root->op) && (root->mark & BRACKETSMARK) != BRACKETSMARK)
{
bintree *rp = root;
while(getlevel(rp->rchild->op) != 0 && getlevel(subexprtree->op) > getlevel(rp->rchild->op) && (rp->rchild->mark & BRACKETSMARK) != BRACKETSMARK)
{
rp = rp->rchild;
}
subexprtree->lchild = rp->rchild;
rp->rchild = subexprtree;
}
else
{
subexprtree->lchild = root;
root = subexprtree;
}
}
else if (**ptr == ')')
{
if (ptrnum != numstr)
{
*ptrnum = '\0';
appendnode(&root, op, atof(numstr));
}
(*ptr)++;
root->mark |= BRACKETSMARK;
return root;
}
else if (ptrnum != numstr)
{
*ptrnum = '\0';
appendnode(&root, op, atof(numstr));
ptrnum = numstr;
op = **ptr;
(*ptr)++;
}
else
{
op = **ptr;
(*ptr)++;
}
}
else
{
*ptrnum++ = **ptr;
(*ptr)++;
}
}
if (ptrnum != numstr)
{
*ptrnum = '\0';
appendnode(&root, op, atof(numstr));
}
}
return root;
}
bintree *createtree(const char *szexpress)
{
const char *ptr = szexpress;
return createtree_(&ptr);
}