采用先序序列输入,二叉链表存储结构,非递归方式建立二叉树。

 


对于非递归算法建立二叉树可以参考迷宫算法给出;

 

  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3. #include<conio.h> 
  4.  
  5. typedef struct tree 
  6.     char ch; 
  7.     struct tree *lchild; 
  8.     struct tree *rchild; 
  9.     int flag; 
  10. }TREE; 
  11.  
  12. typedef struct 
  13.     TREE *elem[30]; 
  14.     int top; 
  15. }STACK; 
  16.  
  17. void initStack(STACK *S); 
  18. int push(STACK *S, TREE *x); 
  19. int pop(STACK *S, TREE **x); 
  20. int Pass(TREE *p); 
  21. TREE *createTree(); 
  22. void fristRoot(TREE *root); 
  23. void middleRoot(TREE *root); 
  24. void lastRoot(TREE *root); 
  25. void destroyTree(TREE *root); 
  26.  
  27. int main() 
  28.     TREE *root; 
  29.  
  30.     root = createTree(); 
  31.     printf("\n先序:\n"); 
  32.     fristRoot(root); 
  33.     printf("\n中序:\n"); 
  34.     middleRoot(root); 
  35.     printf("\n后序:\n"); 
  36.     lastRoot(root); 
  37.     printf("\n");  
  38.  
  39.     destroyTree(root); 
  40.     return 0; 
  41.  
  42. void initStack(STACK *S) 
  43.     S->top = -1; 
  44.  
  45. int push(STACK *S, TREE *x) 
  46.     if (S->top >= 29) 
  47.         return 0; 
  48.     S->top++; 
  49.     S->elem[S->top] = x; 
  50.     return 1; 
  51.  
  52. int pop(STACK *S, TREE **x) 
  53.     if (S->top < 0) 
  54.         return 0; 
  55.     *x = S->elem[S->top]; 
  56.     S->top--; 
  57.     return 1; 
  58.  
  59. int Pass(TREE *p) 
  60.     if (p->lchild == NULL) 
  61.         if (p->rchild == NULL) 
  62.             return 0; 
  63.         else 
  64.             if (p->rchild->flag) 
  65.                 return 0; 
  66.             else 
  67.                 return 2; 
  68.     else 
  69.         if (p->lchild->flag) 
  70.             if (p->rchild == NULL) 
  71.                 return 0; 
  72.             else 
  73.                 if (p->rchild->flag) 
  74.                     return 0; 
  75.                 else 
  76.                     return 2; 
  77.         else 
  78.             if (p->rchild == NULL) 
  79.                 return -1; 
  80.             else 
  81.                 if (p->rchild->flag) 
  82.                     return -1; 
  83.                 else 
  84.                     return 1; 
  85.  
  86. TREE *createTree() 
  87.     char ch; 
  88.     STACK S; 
  89.     TREE *root, *p, *q, *temp; 
  90.     int i, ret; 
  91.  
  92.     initStack(&S); 
  93.     root = (TREE *)malloc(sizeof(TREE)); 
  94.     printf("Please input string:\n"); 
  95.     ch = getche(); 
  96.     root->ch = ch; 
  97.     p = root; 
  98.     p->lchild = p->rchild = p; 
  99.     p->flag = 0; 
  100.     push(&S, p); 
  101.     i = 0; 
  102.     do
  103.         if( (ret = Pass(p) ) > 0 ) 
  104.         { 
  105.             ch = getche(); 
  106.             if(ch != ' '
  107.             { 
  108.                 q = (TREE *)malloc(sizeof(TREE)); 
  109.                 q->ch = ch; 
  110.                 q->lchild = q->rchild = q; 
  111.                 q->flag = 0; 
  112.                 push(&S, q); 
  113.             } 
  114.             else 
  115.                 q = NULL; 
  116.             if (ret == 1) 
  117.                 p->lchild = q; 
  118.             else if (ret == 2) 
  119.                 p->rchild = q;       
  120.         } 
  121.         else 
  122.             pop(&S, &temp); 
  123.         if(S.top > -1) 
  124.         { 
  125.             p->flag = 1; 
  126.             if(p->lchild != p && p->rchild == p) 
  127.                 p->flag = 0; 
  128.             p = S.elem[S.top]; 
  129.         } 
  130.     }while(S.top > -1); 
  131.  
  132.     return root; 
  133.  
  134. void fristRoot(TREE *root) 
  135.     TREE *p; 
  136.     STACK S; 
  137.     initStack(&S); 
  138.     p = root; 
  139.     while( p || S.top > -1) 
  140.     { 
  141.  
  142.         while(p) 
  143.         { 
  144.             printf("%c ",p->ch); 
  145.             push(&S, p); 
  146.             p = p->lchild; 
  147.         } 
  148.         if(!p) 
  149.         { 
  150.             pop(&S, &p); 
  151.             p = p->rchild; 
  152.         } 
  153.  
  154.     } 
  155.  
  156. void middleRoot(TREE *root) 
  157.     TREE *p; 
  158.     STACK S; 
  159.     initStack(&S); 
  160.     p = root; 
  161.     while(p || S.top > -1) 
  162.     { 
  163.         if(p) 
  164.         { 
  165.             push(&S, p); 
  166.             p = p->lchild; 
  167.         } 
  168.         else 
  169.         { 
  170.             pop(&S, &p); 
  171.             printf("%c ",p->ch); 
  172.             p = p->rchild; 
  173.         } 
  174.     } 
  175.  
  176. void lastRoot(TREE *root) 
  177.     TREE *p, *q; 
  178.     STACK S; 
  179.     initStack(&S); 
  180.     p = root; 
  181.     while(p || S.top != -1) 
  182.     { 
  183.         while(p) 
  184.         { 
  185.             push(&S, p); 
  186.             p = p->lchild; 
  187.         } 
  188.         if(S.top > -1) 
  189.         { 
  190.             p = S.elem[S.top]; 
  191.             if(p->rchild == NULL || p->rchild == q) 
  192.             { 
  193.                 printf("%c ",p->ch); 
  194.                 q = p; 
  195.                 S.top--; 
  196.                 p = NULL; 
  197.             } 
  198.             else 
  199.                 p = p->rchild; 
  200.         } 
  201.          
  202.     } 
  203.  
  204. void destroyTree(TREE *root) 
  205.     if (root != NULL) 
  206.     { 
  207.         destroyTree(root->lchild); 
  208.         destroyTree(root->rchild); 
  209.         free(root); 
  210.     } 

二叉树的定义:

  1. typedef struct tree 
  2.     char ch; 
  3.     struct tree *lchild; 
  4.     struct tree *rchild; 
  5.     int flag; 
  6. }TREE; 
flag主要用于标记该节点是否处理过; 对于Pass函数(改函数主要判断其左右孩子是否处理)的详细解释:

假设p为根节点,  其左孩子为p->lchild    右孩子为p->rchild

  条件   返回值
1 p->lchild == NULL && p->rchild == NULL 不可通过 0
2 p->lchild == NULL && p->rchild != NULL && p->rchild->flag == 0 右子树可通过 2
3 p->lchild == NULL && p->rchild != NULL && p->rchild->flag == 1 不可通过 0
4 p->lchild != NULL && p->lchild->flag == 0 && p->rchild == NULL 此情况不会发生  
5

p->lchild != NULL && p->lchild->flag == 0 &&

    p->rchild != NULL && p->rchild->flag == 0

左子树可通过 1
6

p->lchild!=NULL && p->lchild->flag == 0 &&

    p->rchild != NULL && p->rchild->flag == 1

此情况不会发生  
7 p->lchild!=NULL && p->lchild->flag == 1 && p->rchild == NULL 不可通过 0
8

p->lchild!=NULL && p->lchild->flag == 1

    p->rchild != NULL && p->rchild->flag == 0

右子树可通过 2
9

p->lchild!=NULL && p->lchild->flag == 1 

    p->rchild != NULL && p->rchild->flag == 1

不可通过 0