将二叉树转换为森林

 

  1. #include<stdio.h>  
  2. /*树,二叉链表表示(左右链), 实现前序、后序、层序遍历的同时,把它转化为森林后的结果打印出来  
  3. */ 
  4. //输入样例:ABDH##I##E##CF#J##G##  
  5. struct node  
  6. {  
  7.     struct node *lchild;  
  8.     struct node *rchild;  
  9.     char data;  
  10. };  
  11.  
  12. typedef struct node *BTREE;  
  13.  
  14. int IsEmpty(BTREE BT)  
  15. {  
  16.     if(BT==NULL)  
  17.         return 1;  
  18.     else 
  19.         return 0;  
  20. }  
  21.  
  22. BTREE Lchild(BTREE BT)  
  23. {  
  24.     return BT->lchild;  
  25. }  
  26.  
  27. BTREE Rchild(BTREE BT)  
  28. {  
  29.     return BT->rchild;  
  30. }  
  31.  
  32. char Data(BTREE BT)  
  33. {  
  34.     if(BT!=NULL)  
  35.         return BT->data;  
  36.     else 
  37.         return 0;  
  38. }  
  39.  
  40. void visit(char x)  
  41. {  
  42.     printf("%c", x);  
  43. }  
  44.  
  45. void CreateBT(BTREE &T)//按先根顺序输入二叉树  
  46. {  
  47.     char ch;  
  48.     scanf("%c", &ch);  
  49.     if(ch=='#')  
  50.         T=NULL;  
  51.     else 
  52.     {  
  53.         if(!(T=new node))  
  54.             printf("Error!");  
  55.         T->data=ch;  
  56.         CreateBT(T->lchild);  
  57.         CreateBT(T->rchild);  
  58.     }  
  59. }  
  60.  
  61.  
  62. void PreOrder(BTREE BT)  
  63. {  
  64.     if(!IsEmpty(BT))  
  65.     {  
  66.         visit(Data(BT));  
  67.         PreOrder(Lchild(BT));  
  68.         PreOrder(Rchild(BT));  
  69.     }  
  70. }  
  71.  
  72. void PostOrder(BTREE BT)  
  73. {  
  74.     if(!IsEmpty(BT))  
  75.     {  
  76.         PostOrder(Lchild(BT));  
  77.         PostOrder(Rchild(BT));  
  78.         visit(Data(BT));  
  79.     }  
  80. }  
  81.  
  82. struct celltype//队列  
  83. {  
  84.     BTREE element;  
  85.     celltype *next;  
  86. };  
  87.  
  88. struct Queue//队列  
  89. {  
  90.     celltype *front;  
  91.     celltype *rear;  
  92. };  
  93.  
  94. void MakeNull(Queue &Q)//队列  
  95. {  
  96.     Q.front=new celltype;  
  97.     Q.front->next=NULL;  
  98.     Q.rear=Q.front;  
  99. }  
  100.  
  101. int Empty(Queue Q)//队列  
  102. {  
  103.     if(Q.front==Q.rear)  
  104.         return 1;  
  105.     else 
  106.         return 0;  
  107. }  
  108.  
  109. BTREE Front(Queue Q)//队列  
  110. {  
  111.     return Q.front->next->element;  
  112. }  
  113.  
  114. void EnQueue(BTREE c, Queue &Q)//队列  
  115. {  
  116.     Q.rear->next=new celltype;  
  117.     Q.rear=Q.rear->next;  
  118.     Q.rear->element=c;  
  119.     Q.rear->next=NULL;  
  120. }  
  121.  
  122. void DeQueue(Queue &Q)//队列  
  123. {  
  124.     celltype *temp;  
  125.     if(Empty(Q))  
  126.         printf("队列是空的!");  
  127.     else 
  128.     {  
  129.         temp=Q.front->next;  
  130.         Q.front->next=temp->next;  
  131.         delete temp;  
  132.         if(Q.front->next==NULL)  
  133.             Q.rear=Q.front;  
  134.     }  
  135. }  
  136.  
  137. void Level(BTREE BT)//按层遍历  
  138. {  
  139.     Queue Q;  
  140.     BTREE T;  
  141.     MakeNull(Q);  
  142.     T=BT;  
  143.     EnQueue(T, Q);  
  144.     while(!(Empty(Q)))  
  145.     {  
  146.         T=Front(Q);  
  147.         DeQueue(Q);  
  148.         visit(T->data);  
  149.         if(T->lchild!=NULL)  
  150.             EnQueue(T->lchild, Q);  
  151.         if(T->rchild!=NULL)  
  152.             EnQueue(T->rchild, Q);  
  153.     }  
  154. }  
  155.  
  156. int TreeToForest(BTREE &T, BTREE forest[])//forest 里面存的是各个树的根节点  
  157. {  
  158.     BTREE p;  
  159.     int i, j, n;  
  160.     n=1;  
  161.     forest[0]=T;  
  162.  
  163.     for(i=0; i<n; i++) //第一遍循环,把根的右子树、右子树的右子树....全放进数组  
  164.     {  
  165.         if(forest[i]->rchild)  
  166.         {  
  167.             forest[n++]=forest[i]->rchild;  
  168.             forest[i]->rchild=NULL;  
  169.         }//把右儿子切掉放在数组里  
  170.  
  171.     }  
  172.     for(j=0; j<n; j++) //第二遍循环,把数组中每个元素的左子树的右子树、左子树的左子树的右子树...放进数组  
  173.     {  
  174.         p=forest[j]->lchild;  
  175.         while(p)  
  176.         {  
  177.             if(p->rchild!=NULL )  
  178.             {  
  179.                 forest[n++]=p->rchild;  
  180.             }  
  181.             p=p->lchild;  
  182.         }  
  183.     }  
  184.     return n;  
  185.  
  186. }  
  187.  
  188. int main()  
  189. {  
  190.     //ABDH##I##E##CF#J##G##  
  191.     BTREE tree, p;  
  192.     int n, i;  
  193.     BTREE forest[100];//存放转化为森林后的各个树根  
  194.     printf("请桉先根顺序输入二叉树(用#表示子树不存在):\n");  
  195.     CreateBT(tree);  
  196.     /*  
  197.     printf("\n先根遍历的结果为:\n");  
  198.     PreOrder(tree);  
  199.     printf("\n\n后根遍历的结果为:\n");  
  200.     PostOrder(tree);  
  201.     printf("\n按层遍历的结果为:\n");  
  202.     Level(tree);  
  203.     printf("\n\n转换为森林的结果为:\n");  
  204.     n=TreeToForest(tree, forest);  
  205.  
  206.     for(i=0;i<n;i++)  
  207.     {  
  208.         printf("\n第%d棵树的根节点为: %c", i+1, forest[i]->data);  
  209.         if(forest[i]->lchild)  
  210.         {  
  211.         printf("\n  它的子节点元素为:");  
  212.         p=forest[i]->lchild;}  
  213.         else{printf(" (无儿子)");}  
  214.         while(p)  
  215.         {  
  216.             printf(" %c", p->data);  
  217.             p=p->lchild;  
  218.         }  
  219.         printf("\n");  
  220.     }  
  221.  
  222.     getchar();  
  223.     return 0;  
  224. }