构造一棵表达式二叉树

下面这个程序是我看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. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值