用二叉树求解代数表达式

来源:互联网 发布:免费聊天相亲软件 编辑:程序博客网 时间:2024/04/29 02:58

  1. #include <stdio.h>  
  2. #include <malloc.h>  
  3. #include<string.h>  
  4. #include <stdlib.h>    
  5. #define MaxSize 100  
  6. typedef char ElemType;  
  7. typedef struct node  
  8. {  
  9.     ElemType data;              //数据元素  
  10.     struct node *lchild;        //指向左孩子  
  11.     struct node *rchild;        //指向右孩子  
  12. } BTNode;  
  13. void CreateBTNode(BTNode *&b,char *str);        //由str串创建二叉链  
  14. BTNode *FindNode(BTNode *b,ElemType x);     //返回data域为x的节点指针  
  15. BTNode *LchildNode(BTNode *p);  //返回*p节点的左孩子节点指针  
  16. BTNode *RchildNode(BTNode *p);  //返回*p节点的右孩子节点指针  
  17. int BTNodeDepth(BTNode *b); //求二叉树b的深度  
  18. void DispBTNode(BTNode *b); //以括号表示法输出二叉树  
  19. void DestroyBTNode(BTNode *&b);  //销毁二叉树  
  20.   
  21. void CreateBTNode(BTNode *&b,char *str)     //由str串创建二叉链  
  22. {  
  23.     BTNode *St[MaxSize],*p=NULL;  
  24.     int top=-1,k,j=0;  
  25.     char ch;  
  26.     b=NULL;             //建立的二叉树初始时为空  
  27.     ch=str[j];  
  28.     while (ch!='\0')    //str未扫描完时循环  
  29.     {  
  30.         switch(ch)  
  31.         {  
  32.         case '(':  
  33.             top++;  
  34.             St[top]=p;  
  35.             k=1;  
  36.             break;      //为左节点  
  37.         case ')':  
  38.             top--;  
  39.             break;  
  40.         case ',':  
  41.             k=2;  
  42.             break;                          //为右节点  
  43.         default:  
  44.             p=(BTNode *)malloc(sizeof(BTNode));  
  45.             p->data=ch;  
  46.             p->lchild=p->rchild=NULL;  
  47.             if (b==NULL)                    //p指向二叉树的根节点  
  48.                 b=p;  
  49.             else                            //已建立二叉树根节点  
  50.             {  
  51.                 switch(k)  
  52.                 {  
  53.                 case 1:  
  54.                     St[top]->lchild=p;  
  55.                     break;  
  56.                 case 2:  
  57.                     St[top]->rchild=p;  
  58.                     break;  
  59.                 }  
  60.             }  
  61.         }  
  62.         j++;  
  63.         ch=str[j];  
  64.     }  
  65. }  
  66. BTNode *FindNode(BTNode *b,ElemType x)  //返回data域为x的节点指针  
  67. {  
  68.     BTNode *p;  
  69.     if (b==NULL)  
  70.         return NULL;  
  71.     else if (b->data==x)  
  72.         return b;  
  73.     else  
  74.     {  
  75.         p=FindNode(b->lchild,x);  
  76.         if (p!=NULL)  
  77.             return p;  
  78.         else  
  79.             return FindNode(b->rchild,x);  
  80.     }  
  81. }  
  82. BTNode *LchildNode(BTNode *p)   //返回*p节点的左孩子节点指针  
  83. {  
  84.     return p->lchild;  
  85. }  
  86. BTNode *RchildNode(BTNode *p)   //返回*p节点的右孩子节点指针  
  87. {  
  88.     return p->rchild;  
  89. }  
  90. int BTNodeDepth(BTNode *b)  //求二叉树b的深度  
  91. {  
  92.     int lchilddep,rchilddep;  
  93.     if (b==NULL)  
  94.         return(0);                          //空树的高度为0  
  95.     else  
  96.     {  
  97.         lchilddep=BTNodeDepth(b->lchild);   //求左子树的高度为lchilddep  
  98.         rchilddep=BTNodeDepth(b->rchild);   //求右子树的高度为rchilddep  
  99.         return (lchilddep>rchilddep)? (lchilddep+1):(rchilddep+1);  
  100.     }  
  101. }  
  102. void DispBTNode(BTNode *b)  //以括号表示法输出二叉树  
  103. {  
  104.     if (b!=NULL)  
  105.     {  
  106.         printf("%c",b->data);  
  107.         if (b->lchild!=NULL || b->rchild!=NULL)  
  108.         {  
  109.             printf("(");  
  110.             DispBTNode(b->lchild);  
  111.             if (b->rchild!=NULL) printf(",");  
  112.             DispBTNode(b->rchild);  
  113.             printf(")");  
  114.         }  
  115.     }  
  116. }  
  117. void DestroyBTNode(BTNode *&b)   //销毁二叉树  
  118. {  
  119.     if (b!=NULL)  
  120.     {  
  121.         DestroyBTNode(b->lchild);  
  122.         DestroyBTNode(b->rchild);  
  123.         free(b);  
  124.     }  
  125. }  
  126.   
  127.   
  128. //用s[i]到s[j]之间的字符串,构造二叉树的表示形式  
  129. BTNode *CRTree(char s[],int i,int j)  
  130. {  
  131.     BTNode *p;  
  132.     int k,plus=0,posi;  
  133.     if (i==j)    //i和j相同,意味着只有一个字符,构造的是一个叶子节点  
  134.     {  
  135.         p=(BTNode *)malloc(sizeof(BTNode));   //分配存储空间  
  136.         p->data=s[i];                         //值为s[i]  
  137.         p->lchild=NULL;  
  138.         p->rchild=NULL;  
  139.         return p;  
  140.     }  
  141.     //以下为i!=j的情况  
  142.     for (k=i; k<=j; k++)  
  143.         if (s[k]=='+' || s[k]=='-')  
  144.         {  
  145.             plus++;  
  146.             posi=k;              //最后一个+或-的位置  
  147.         }  
  148.     if (plus==0)                 //没有+或-的情况(因为若有+、-,前面必会执行plus++)  
  149.         for (k=i; k<=j; k++)  
  150.             if (s[k]=='*' || s[k]=='/')  
  151.             {  
  152.                 plus++;  
  153.                 posi=k;  
  154.             }  
  155.     //以上的处理考虑了优先将+、-放到二叉树较高的层次上  
  156.     //由于将来计算时,运用的是后序遍历的思路  
  157.     //处于较低层的乘除会优先运算  
  158.     //从而体现了“先乘除后加减”的运算法则  
  159.     //创建一个分支节点,用检测到的运算符作为节点值  
  160.     if (plus!=0)  
  161.     {  
  162.         p=(BTNode *)malloc(sizeof(BTNode));  
  163.         p->data=s[posi];                //节点值是s[posi]  
  164.         p->lchild=CRTree(s,i,posi-1);   //左子树由s[i]至s[posi-1]构成  
  165.         p->rchild=CRTree(s,posi+1,j);   //右子树由s[poso+1]到s[j]构成  
  166.         return p;  
  167.     }  
  168.     else       //若没有任何运算符,返回NULL  
  169.         return NULL;  
  170. }  
  171.   
  172. double Comp(BTNode *b)  
  173. {  
  174.     double v1,v2;  
  175.     if (b==NULL)  
  176.         return 0;  
  177.     if (b->lchild==NULL && b->rchild==NULL)  //叶子节点,应该是一个数字字符(本项目未考虑非法表达式)  
  178.         return b->data-'0';    //叶子节点直接返回节点值,结点中保存的数字用的是字符形式,所以要-'0'  
  179.     v1=Comp(b->lchild); //先计算左子树  
  180.     v2=Comp(b->rchild); //再计算右子树  
  181.     switch(b->data)     //将左、右子树运算的结果再进行运算,运用的是后序遍历的思路  
  182.     {  
  183.     case '+':  
  184.         return v1+v2;  
  185.     case '-':  
  186.         return v1-v2;  
  187.     case '*':  
  188.         return v1*v2;  
  189.     case '/':  
  190.         if (v2!=0)  
  191.             return v1/v2;  
  192.         else  
  193.             abort();  
  194.     }  
  195. }  
  196.   
  197. int main()  
  198. {  
  199.     BTNode *b;  
  200.     char s[MaxSize]="1+2*3-4/5";  
  201.     printf("代数表达式%s\n",s);  
  202.     b=CRTree(s,0,strlen(s)-1);  
  203.     printf("对应二叉树:");  
  204.     DispBTNode(b);  
  205.     printf("\n表达式的值:%g\n",Comp(b));  
  206.     DestroyBTNode(b);  
  207.     return 0;  
  208. }  


0 0