`
pleasetojava
  • 浏览: 703078 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

构造一棵表达式二叉树

阅读更多

下面这个程序是我看weiss的《数据结构与算法分析》的第四章的树里面的一个算法写的程序,具体可以看该书的第一版的71页这个给出我的实现,希望来者给出更加好的设计思路。

程序里面给出了8种遍历方式,欧拉遍历(其实就是中序加了两个括号而已),前序非递归,中序非递归,后序非递归,前序递归,中序递归,后序递归,

另外程序也添加了按层遍历二叉树,程序如下:

  1. #include<ctype.h>
  2. #include<malloc.h>
  3. #include<stdio.h>
  4. #include<queue>
  5. usingnamespacestd;
  6. typedefstructTreenode*ptrtonode;
  7. typedefptrtonodeTree;
  8. structTreenode{
  9. charx;
  10. Treelefttree;
  11. Treerighttree;
  12. }Treenode;
  13. typedefstructList_Stack{
  14. structList_Stack*next;
  15. Treemytree;
  16. }Node,*LS;
  17. voidinitstack(LS*a){
  18. (*a)=(LS)malloc(sizeof(Node));
  19. (*a)->next=NULL;
  20. }
  21. boolstackempty(constLSa){
  22. returna->next==NULL;
  23. }
  24. /*链栈一般不会满,不测试
  25. boolstackfull(constLSa){
  26. return!stackempty(a);
  27. }
  28. */
  29. voidpush(LS*lstack,Treea){
  30. LSres=(LS)malloc(sizeof(Node));
  31. res->mytree=a;
  32. res->next=(*lstack)->next;
  33. (*lstack)->next=res;
  34. }
  35. Treepop(LS*lstack){
  36. if(stackempty(*lstack)){
  37. printf("Poperror,stackisempty!\n");
  38. returnNULL;//打印一个笑脸
  39. }
  40. LSp=(*lstack)->next;
  41. Treex=p->mytree;
  42. LSpnext=p->next;
  43. //free(p);
  44. (*lstack)->next=pnext;
  45. returnx;
  46. }
  47. boolisoperator(chara){
  48. if(a=='-'||a=='+'||a=='*'||a=='/')
  49. return1;
  50. else
  51. return0;
  52. }
  53. Treechartotree(chara){
  54. Treemytree=(Tree)malloc(sizeof(Treenode));
  55. mytree->x=a;
  56. mytree->lefttree=mytree->righttree=NULL;
  57. returnmytree;
  58. }
  59. boolexnode(Treex){//外节点,也就是叶子节点
  60. if((x->righttree==NULL)&&(x->lefttree==NULL)){
  61. return1;
  62. }
  63. else
  64. return0;
  65. }
  66. boolinnode(Treex){//内节点,也就是中间节点
  67. return!exnode(x);
  68. }
  69. //欧拉遍历方式,跟中序遍历类似
  70. voideulervisit(Treex){
  71. if(exnode(x)){
  72. printf("%c",x->x);
  73. }
  74. else{
  75. printf("(");
  76. eulervisit(x->lefttree);
  77. printf("%c",x->x);
  78. eulervisit(x->righttree);
  79. printf(")");
  80. }
  81. }
  82. //中序递归的遍历方式
  83. boolmidvisit(Treex){
  84. if(x){
  85. if(midvisit(x->lefttree))
  86. if(printf("%c",x->x))
  87. if(midvisit(x->righttree))
  88. return1;
  89. return0;
  90. }
  91. else
  92. return1;
  93. }
  94. //前序递归的遍历方式
  95. boolprevisit(Treex){
  96. if(x){
  97. if(printf("%c",x->x))
  98. if(previsit(x->lefttree))
  99. if(previsit(x->righttree))
  100. return1;
  101. return0;
  102. }
  103. else
  104. return1;
  105. }
  106. //后序递归的遍历方式
  107. voidpostvisit(Treex){
  108. if(x){
  109. postvisit(x->lefttree);
  110. postvisit(x->righttree);
  111. printf("%c",x->x);
  112. }
  113. }
  114. //前序的非递归遍历
  115. voidpreordervisit(Treex){
  116. LSa;
  117. initstack(&a);
  118. Treep=x;
  119. while(p||!stackempty(a))
  120. {
  121. if(p)
  122. {
  123. push(&a,p);
  124. printf("%c",p->x);
  125. p=p->lefttree;
  126. }
  127. else{
  128. p=pop(&a);
  129. p=p->righttree;
  130. }
  131. }
  132. }
  133. //中序的非递归遍历
  134. voidinordervisit(Treex){
  135. LSa;
  136. initstack(&a);
  137. Treep=x;
  138. while(p||!stackempty(a))
  139. {
  140. if(p)
  141. {
  142. push(&a,p);
  143. p=p->lefttree;
  144. }
  145. else{
  146. p=pop(&a);
  147. printf("%c",p->x);
  148. p=p->righttree;
  149. }
  150. }
  151. }
  152. /***********************************************************************
  153. /*后序的非递归遍历,后序遍历有点复杂,
  154. /*要给出一个标记表明左边和右边子树都已经遍历,
  155. /*这里就不使用开始时候的堆栈了,
  156. /*用数组堆栈实现效果更加好,惟一的缺点就是堆栈有最大限制*/
  157. /************************************************************************/
  158. voidpostordervisit(Treex){
  159. Treestack[100],p;
  160. inttag[100],top;
  161. top=0;
  162. p=x;
  163. do
  164. {
  165. while(p!=NULL)//扫描左子树,入栈
  166. {
  167. top++;
  168. stack[top]=p;
  169. tag[top]=0;//右边子树还没有访问设置为0
  170. p=p->lefttree;
  171. }
  172. if(top>0)
  173. {
  174. if(tag[top]==1)
  175. {
  176. printf("%c",stack[top]->x);
  177. top--;
  178. }
  179. else{
  180. p=stack[top];
  181. if(top>0)
  182. {
  183. p=p->righttree;
  184. tag[top]=1;
  185. }
  186. }
  187. }
  188. }while((p!=NULL)||(top!=0));
  189. }
  190. Treecreatetree(char*a){//根据数据结构与算法分析的71页的算法设计一个表达式树
  191. LSx;
  192. initstack(&x);
  193. char*p=a;
  194. while(*p!='\0'){
  195. Treea,b;
  196. Treemytree;
  197. if(isalpha(*p)){
  198. mytree=chartotree(*p);
  199. push(&x,mytree);
  200. }
  201. if(isoperator(*p)){
  202. mytree=chartotree(*p);
  203. a=pop(&x);
  204. b=pop(&x);
  205. mytree->righttree=a;
  206. mytree->lefttree=b;
  207. push(&x,mytree);
  208. }
  209. p++;
  210. }
  211. Treeroot=pop(&x);
  212. returnroot;
  213. }
  214. voiddeletenode(Tree*p){//按层遍历
  215. queue<Tree>que;
  216. que.push(*p);
  217. Treetemp;
  218. while(!que.empty()){
  219. temp=que.front();
  220. que.pop();
  221. if(temp->lefttree)
  222. que.push(temp->lefttree);
  223. if(temp->righttree)
  224. que.push(temp->righttree);
  225. //free(temp);
  226. printf("%c",temp->x);
  227. temp=NULL;
  228. }
  229. }
  230. intmain(intargc,char*argv[])
  231. {
  232. LSx;
  233. initstack(&x);
  234. if(stackempty(x))
  235. printf("stackisempty!\n");
  236. else
  237. printf("stackisfull!\n");
  238. printf("%c\n",pop(&x));
  239. char*p="abc*+b-";
  240. Treeroot=createtree(p);
  241. //等待进一步的实现来实现二叉树的遍历
  242. //用到exnode和innode函数
  243. eulervisit(root);
  244. puts("\n中序递归");
  245. midvisit(root);
  246. puts("\n中序非递归");
  247. inordervisit(root);
  248. puts("\n前序递归");
  249. previsit(root);
  250. puts("\n前序非递归");
  251. preordervisit(root);
  252. puts("\n后序递归");
  253. postvisit(root);
  254. puts("\n后序非递归");
  255. postordervisit(root);
  256. deletenode(&root);
  257. return0;
  258. }
分享到:
评论

相关推荐

    算术表达式和二叉树-数据结构课设

    (1) ReadExpre(E)- _以字符序列的形式输入语法正确的前缀表达式并构造表达式E。(2) WriteExpre(E)- 用带括弧的中缀表达式输出表达式E。 (3) Assign(V,c)-实现对变量 V的赋值(V=c), 变量的初值为0。 (4) Value(E)-对...

    二叉树建立还有后序计算表达式

    1、设计一个程序,根据二叉树的先根序列和中根序列创建一棵用左右指针表示的二叉树 例如:先根序列为 ABDGCEF#, 中根序列为 DGBAECF# (#表示结束)。然后用程序构造一棵二叉树。注意程序的通用性(也就是说上述只是...

    二叉树的基本运算 数据结构

    1. 按先序序列构造一棵二叉链表表示的二叉树T; 2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列; 3. 求二叉树的深度/结点数目/叶结点数目;(选做) 4. 将二叉树每个结点的左右子树...

    Jo.rar_jo

    对于任意给出的前缀或中缀或后缀表达式,构造一棵表达式二叉树并表示出来,对于构造好的二叉树,输出相应的前中后缀表达式。

    算术表达式与二叉树.docx

    (5) CompoundExpr (P, E1,E2) -_构造-一个新的复合表达式(E1) P (E2) [测试数据] (1)分别输入 0; a; -91; +a*bc; +*5^x2*8x; +++*3^x3*2^x2x6 并输出。 (2)每当输入一个表达式后,对其中的变量赋值,然后对表达式...

    数据课设报告书-表达式类型的实现(完整的课设报告+源代码)

    1. ReadExpr(E)——以字符序列的形式输入语法正确的前缀表示式并构造表达式E。 2. WriteExpr(E)——用带括号的中缀表示式输出表达式E。 3. Assign(V,c)——实现对变量V的赋值(V=c),变量的初值为0。 4. Value...

    山东大学数据结构课设表达式类型 源.cpp

    (1)ReadExpr(E)――以字符序列的形式输入语法正确的前缀表达式并构造表达式E。 (2)WriteExpr(E)――用带括号的中缀表达式输出表达式E。 (3)Assign(V,c)――实现对变量V的赋值(V=c),变量的初值为0。 ...

    数据课设报告书x_数学分析结课报告

    1. ReadExpr(E)——以字符序列的形式输入语法正确的前缀表示式并构造表达式E。 2. WriteExpr(E)——用带括号的中缀表示式输出表达式E。 3. Assign(V,c)——实现对变量V的赋值(V=c),变量的初值为0。 4. Value...

    java前序中序构造二叉树

    已知前序中序 构造二叉树,并求后序遍历 判断是否为平衡二叉树

    数据结构(c语言)单链表 表达式求值 二叉树 二叉排序树 Huffman编码

    数据结构课设,用c语言编写的单链表, 表达式求值, 二叉树 ,二叉排序树 ,Huffman编码,五个做成菜单,只有一个main函数

    二叉树可视化构造及相关操作(数据结构学习专用)

    c#实现的二叉树构造,遍历,二叉树后缀表达式求值等算法。可以用于数据结构教学

    二叉树的括号表示法,二叉树的遍历,二叉树的树形打印输出(C++)

    根据括号表达式构造二叉树,对二叉树进行前序,中序,后序,层序遍历,并用树形方式打印输出,有详细注释,供C++数据结构课程学习与交流使用。

    tree_遍历_ideawfi_二叉树_数据结构_

    构造表达式二叉树,实现二叉树的递归与非递归的先序、中序、后序遍历,求二叉树的宽度、深度、结点的父子结点等。

    数据结构与算法实验报告

    1 实验一 线性链表及应用 1 1.1 实验目的 1 1.2 实验要求 1 1.3 实验内容 1 1.3.1 线性链表ADT定义及其实现 1 1.3.2 线性链表ADT测试程序 3 1.3.3 线性链表的应用 4 1.4 线性链表实现与测试总结 5 2 实验二 栈及应用...

    上机实验3-二叉树

    1.输入一个中缀表达式,构造表达式树,以文本方式输出树结构。 输入:例如,输入a+b+c*(d+e) 输出:以缩进表示二叉树的层次,左(根),右(叶),上(右子树),下(左子树) 2.编写二叉树类的成员函数,分别实现...

    将逆波兰式转换成波兰式表达式

    这是严蔚敏《数据结构》配套习题册上的题目:将逆波兰式转换成波兰式,并提示错误(作为简化,只处理"+-*/"和0~9的数字)。... 算法是根据后根遍历的序列构造一个表达式树,进而先根遍历此树获得波兰式表达式。

    二叉树计数问题的研究

    有关二叉树计数问题的探讨论文,二叉树计数问题是指由n 个节点所构造出的不 同二叉树的数目。这种计数方法与n+ 1 个矩阵连乘 和栈排列n 个数得到的结论是一致的。本文由易到 难叙述问题同解的必然性和可能性, 并给出...

    采用算符优先分析法对表达式进行分析

    1、 实验目的:采用算符优先分析法对表达式进行分析,掌握算符优先分析法的基本原理和实现过程。 2、 实验要求: 文法:无二义性的算术表达式的文法 ...(6)生成一棵语法树(5分)用二叉树的形式表示出来

    数据结构一学期作业(顺序栈,三元组,串,树,邻接表,邻接矩阵,二叉树,等等代码c语言实现)

    2019/11/20 21:49 2,021 二叉树.cpp 2019/09/22 22:58 1,305 复数.cpp 2019/09/25 11:20 1,750 带头结点链表.cpp 2019/11/11 19:51 11,164 广义表.cpp 2019/11/11 20:30 1,917 数组.cpp 2019/09/28 16:28 1,879...

    数据结构实验.rar

    2、(必做题)对于一棵二叉树,请实现: (1)计算二叉树的叶子数目; (2)计算二叉树的深度。 3、(选做题)给定n个权值,请构造它们的最优二叉树(赫夫曼树)。 期末大实验: 一、任意长十进制整数加法 二、...

Global site tag (gtag.js) - Google Analytics