二叉树计算中缀表达式(二)

         二叉树计算中缀表达式,支持指数运算符“^”,暂时不支持括号,直接以字符串形式输入。

#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
#include <malloc.h>

typedef struct tagbintree
{
 char op;
 char level; /* 记录括号 */
 double fvalue;
 struct tagbintree *lchild;
 struct tagbintree *rchild;
}bintree;

char getlevel(char op);
int isop(char c);
double caltree(const bintree *node);
void distree(const bintree *node);
void destorytree(bintree **node);
void appendnode(bintree **node, char op, double value);
bintree *createtree(const char *szexpress);

int main(void)
{
 bintree *root;

 root = createtree("12*15");
 distree(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");
 distree(root);
 printf("\n=%lf\n", caltree(root));
 destorytree(&root);

 printf("\n1+2*3*2^0.5*3^0.3-6\n");
 root = createtree("1+2*3*2^0.5*3^0.3-6");
 distree(root);
 printf("\n=%lf\n", caltree(root));
 destorytree(&root);

 getch();
}

void distree(const bintree *node)
{
 if (node == NULL)
  return;

 distree(node->lchild);
 distree(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->level = getlevel(op);
 node1->fvalue = 0;

 node2 = (bintree *)malloc(sizeof(bintree));
 node2->op = 0;
 node2->level = getlevel(node2->op);
 node2->fvalue = value;
 node2->lchild = NULL;
 node2->rchild = NULL;

 node1->rchild = node2;
 if ((*node)->level != 0 && node1->level > (*node)->level)
  {
   bintree *rp = *node;

   while(rp->rchild->level != 0 && node1->level > rp->rchild->level)
    {
     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 == '^')
  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;
 static char numstr[1024] = {"0"};
 char *ptrnum = numstr;
 bintree *root;

 if (szexpress == NULL)
  return NULL;

 root = (bintree *)malloc(sizeof(bintree));
 if (*ptr == '+' || *ptr == '-')
  {
   root->op = 0;
   root->level = getlevel(root->op);
   root->fvalue = 0;
   root->lchild = NULL;
   root->rchild = NULL;
  }
 else
  {
   while(*ptr)
    {
     if (isop(*ptr))
      break;
     *ptrnum++ = *ptr;
     ptr++;
    }
   *ptrnum = '\0';

   root->op = 0;
   root->level = getlevel(root->op);
   root->fvalue = atof(numstr);
   root->lchild = NULL;
   root->rchild = NULL;
  }

 if (*ptr != '\0')
  {
   op = *ptr;
   ptr++;
   ptrnum = numstr;
   while(*ptr)
    {
     if (isop(*ptr))
      {
       *ptrnum = '\0';
       appendnode(&root, op, atof(numstr));
       ptrnum = numstr;
       op = *ptr;
      }
     else
      *ptrnum++ = *ptr;
     ptr++;
    }
   *ptrnum = '\0';
   appendnode(&root, op, atof(numstr));
  }

 return root;
}


 

为了将二叉树输出中缀表达式,我们可以使用中序遍历的方法。中序遍历是通过先遍历左子树,然后输出根节点,最后遍历右子树的方式。在遍历的过程中,我们需要在适当的位置添加括号。 具体算法的实现如下: 1. 如果当前节点为空,直接返回。 2. 如果当前节点是叶子节点,则输出节点的值。 3. 如果当前节点有左子树,则输出左括号。 4. 递归地遍历左子树。 5. 输出当前节点的值。 6. 如果当前节点有右子树,则输出右括号。 7. 递归地遍历右子树。 以下是一个示例的代码实现: ``` void BtreeToExp(BTree *root){ BtreeToExpHelper(root); } void BtreeToExpHelper(BTree *root){ if (root == NULL){ return; } else if (root->left == NULL && root->right == NULL){ printf("%s", root->data); } else { if (root->left != NULL){ printf("("); } BtreeToExpHelper(root->left); printf("%s", root->data); BtreeToExpHelper(root->right); if (root->right != NULL){ printf(")"); } } } ``` 通过以上算法,我们可以将二叉树输出为中缀表达式。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【数据结构学习笔记】——根据中缀表达式构建二叉树并输出](https://blog.csdn.net/henry903/article/details/50617907)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [算法设计:将给定的二叉树输出其等价的中缀表达式](https://blog.csdn.net/m0_46405703/article/details/127449379)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值