• 二叉树实现表达式求值(C++)


      用二叉树来表示表达式,树的每一个节点包括一个运算符和运算数。代数表达式中只包含+-*/和一位整数且没有错误。按照先括号,再乘除,后加减的规则构造二叉树。如图所示是"1+(2+3)*2-4/5"代数表达式对应二叉树,用对应的二叉树计算表达式的值。

    输入格式:

    输入一行表达式字符串,以#结束,括号内只能有一个运算符。

    输出格式:

    输出表达式的计算结果. 

     

    https://images.ptausercontent.com/364

    1. #include
    2. #include
    3. using namespace std;
    4. typedef struct node
    5. {
    6. char data;
    7. node* lchild, * rchild;
    8. }*tree;
    9. stack expt;
    10. int judge(char ch)//判断是运算符
    11. {
    12. if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#')
    13. return 1;
    14. else
    15. return 0;
    16. }
    17. int jisuan(int n1, int n2, char ch)//计算
    18. {
    19. if (ch == '+')
    20. return n1 + n2;
    21. else if (ch == '-')
    22. return n1 - n2;
    23. else if (ch == '*')
    24. return n1 * n2;
    25. else
    26. return n1 / n2;
    27. }
    28. char Precede(char ch1, char ch2)//判断优先级,ch1栈顶元素
    29. {
    30. char flag = '>';
    31. if (ch1 == '+')
    32. {
    33. switch (ch2)
    34. {
    35. case '+':
    36. case '-':
    37. case '#':
    38. case ')':
    39. flag = '>';
    40. break;
    41. case '*':
    42. case '/':
    43. case '(':
    44. flag = '<';
    45. break;
    46. }
    47. }
    48. else if (ch1 == '-')
    49. {
    50. switch (ch2)
    51. {
    52. case '+':
    53. case '-':
    54. case '#':
    55. flag = '>';
    56. break;
    57. case '*':
    58. case '/':
    59. case '(':
    60. case ')':
    61. flag = '<';
    62. break;
    63. }
    64. }
    65. else if (ch1 == '*')
    66. {
    67. switch (ch2)
    68. {
    69. case '+':
    70. case '-':
    71. case '#':
    72. case '*':
    73. case '/':
    74. case ')':
    75. flag = '>';
    76. break;
    77. case '(':
    78. flag = '<';
    79. break;
    80. }
    81. }
    82. else if (ch1 == '/')
    83. {
    84. switch (ch2)
    85. {
    86. case '+':
    87. case '-':
    88. case '#':
    89. case '*':
    90. case '/':
    91. case ')':
    92. flag = '>';
    93. break;
    94. case '(':
    95. flag = '<';
    96. break;
    97. }
    98. }
    99. else if (ch1 == '(')
    100. {
    101. switch (ch2)
    102. {
    103. case '+':
    104. case '-':
    105. case '*':
    106. case '/':
    107. case '(':
    108. flag = '<';
    109. break;
    110. case ')':
    111. flag = '=';
    112. break;
    113. }
    114. }
    115. else if (ch1 == ')')
    116. {
    117. switch (ch2)
    118. {
    119. case '+':
    120. case '-':
    121. case '*':
    122. case '/':
    123. case ')':
    124. case '#':
    125. flag = '>';
    126. break;
    127. }
    128. }
    129. else if (ch1 == '#')
    130. {
    131. switch (ch2)
    132. {
    133. case '+':
    134. case '-':
    135. case '*':
    136. case '/':
    137. case '(':
    138. flag = '<';
    139. break;
    140. case '#':
    141. flag = '=';
    142. break;
    143. }
    144. }
    145. return flag;
    146. }
    147. void create(tree& t, tree a, tree b, char ch)//构建子树
    148. {
    149. t = new node;
    150. t->data = ch;
    151. t->lchild = a, t->rchild = b;
    152. }
    153. void Createtree()
    154. {
    155. char ch;
    156. stack<char> optr;//运算符
    157. optr.push('#');
    158. cin >> ch;//输入
    159. while (ch != '#' || optr.top() != '#')
    160. {
    161. if (!judge(ch))//不是运算符
    162. {
    163. tree t;
    164. t = new node;
    165. create(t, NULL, NULL, ch);//构建子树,操作数的左右子树为空
    166. expt.push(t);//压入子树栈
    167. cin >> ch;
    168. }
    169. else
    170. {
    171. switch (Precede(optr.top(), ch))
    172. {
    173. case '<'://ch的优先级高于栈顶运算符
    174. optr.push(ch);//ch压入运算符栈
    175. cin >> ch;
    176. break;
    177. case '>'://栈顶运算符优先级高于ch
    178. char yun;
    179. yun = optr.top();//取栈顶运算符
    180. optr.pop();
    181. tree a, b;
    182. a = new node, b = new node;
    183. b = expt.top();//右子树
    184. expt.pop();
    185. a = expt.top();//左子树
    186. expt.pop();
    187. tree t;
    188. t = new node;
    189. create(t, a, b, yun);//以栈顶运算符为根,构建子树
    190. expt.push(t);
    191. break;
    192. case '=':
    193. optr.pop();
    194. cin >> ch;
    195. break;
    196. }
    197. }
    198. }
    199. }
    200. int valuetree(tree t)//树计算
    201. {
    202. int lchild = 0, rchild = 0;
    203. if (t->lchild == NULL && t->rchild == NULL)
    204. return t->data - '0';
    205. else
    206. {
    207. lchild = valuetree(t->lchild);
    208. rchild = valuetree(t->rchild);
    209. return jisuan(lchild, rchild, t->data);
    210. }
    211. }
    212. void printtree(tree t)//中序遍历
    213. {
    214. if (t)
    215. {
    216. printtree(t->lchild);
    217. cout << t->data;
    218. printtree(t->rchild);
    219. }
    220. }
    221. int main()
    222. {
    223. Createtree();
    224. tree t = expt.top();//栈底即为树
    225. //printtree(t);
    226. int a = valuetree(t);
    227. cout << a;
    228. }

  • 相关阅读:
    两个有助于理解Common Lisp宏的例子
    Springboot企业项目管理系统的设计与实现c7ca1计算机毕业设计-课程设计-期末作业-毕设程序代做
    【HCIP】HCIA复习
    【无标题】
    离散数学_十章-图 ( 6 ):欧拉通路与哈密顿通路
    c++入门(二)
    Spire.Office for Java 7.6.4
    企业电子招投标采购系统源码之电子招投标的组成
    GaussDB CN服务异常实例分析
    图论-最短路径问题
  • 原文地址:https://blog.csdn.net/qq_74156152/article/details/133915619