现在的位置: 首页 > 综合 > 正文

构造一棵表达式二叉树

2013年10月22日 ⁄ 综合 ⁄ 共 5907字 ⁄ 字号 评论关闭

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

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

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

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

抱歉!评论已关闭.