二叉樹計算中綴表達式(三)

       二叉樹計算中綴表達式,支持指數運算符“^”,支持括號,以字符串形式輸入。括號通過遞歸處理。下一步要支持科學計數,處理空格正負號,檢查輸入錯誤。

#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);
}


發佈了29 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章