将二叉树转换为森林
- #include<stdio.h>
- /*树,二叉链表表示(左右链), 实现前序、后序、层序遍历的同时,把它转化为森林后的结果打印出来
- */
- //输入样例:ABDH##I##E##CF#J##G##
- struct node
- {
- struct node *lchild;
- struct node *rchild;
- char data;
- };
- typedef struct node *BTREE;
- int IsEmpty(BTREE BT)
- {
- if(BT==NULL)
- return 1;
- else
- return 0;
- }
- BTREE Lchild(BTREE BT)
- {
- return BT->lchild;
- }
- BTREE Rchild(BTREE BT)
- {
- return BT->rchild;
- }
- char Data(BTREE BT)
- {
- if(BT!=NULL)
- return BT->data;
- else
- return 0;
- }
- void visit(char x)
- {
- printf("%c", x);
- }
- void CreateBT(BTREE &T)//按先根顺序输入二叉树
- {
- char ch;
- scanf("%c", &ch);
- if(ch=='#')
- T=NULL;
- else
- {
- if(!(T=new node))
- printf("Error!");
- T->data=ch;
- CreateBT(T->lchild);
- CreateBT(T->rchild);
- }
- }
- void PreOrder(BTREE BT)
- {
- if(!IsEmpty(BT))
- {
- visit(Data(BT));
- PreOrder(Lchild(BT));
- PreOrder(Rchild(BT));
- }
- }
- void PostOrder(BTREE BT)
- {
- if(!IsEmpty(BT))
- {
- PostOrder(Lchild(BT));
- PostOrder(Rchild(BT));
- visit(Data(BT));
- }
- }
- struct celltype//队列
- {
- BTREE element;
- celltype *next;
- };
- struct Queue//队列
- {
- celltype *front;
- celltype *rear;
- };
- void MakeNull(Queue &Q)//队列
- {
- Q.front=new celltype;
- Q.front->next=NULL;
- Q.rear=Q.front;
- }
- int Empty(Queue Q)//队列
- {
- if(Q.front==Q.rear)
- return 1;
- else
- return 0;
- }
- BTREE Front(Queue Q)//队列
- {
- return Q.front->next->element;
- }
- void EnQueue(BTREE c, Queue &Q)//队列
- {
- Q.rear->next=new celltype;
- Q.rear=Q.rear->next;
- Q.rear->element=c;
- Q.rear->next=NULL;
- }
- void DeQueue(Queue &Q)//队列
- {
- celltype *temp;
- if(Empty(Q))
- printf("队列是空的!");
- else
- {
- temp=Q.front->next;
- Q.front->next=temp->next;
- delete temp;
- if(Q.front->next==NULL)
- Q.rear=Q.front;
- }
- }
- void Level(BTREE BT)//按层遍历
- {
- Queue Q;
- BTREE T;
- MakeNull(Q);
- T=BT;
- EnQueue(T, Q);
- while(!(Empty(Q)))
- {
- T=Front(Q);
- DeQueue(Q);
- visit(T->data);
- if(T->lchild!=NULL)
- EnQueue(T->lchild, Q);
- if(T->rchild!=NULL)
- EnQueue(T->rchild, Q);
- }
- }
- int TreeToForest(BTREE &T, BTREE forest[])//forest 里面存的是各个树的根节点
- {
- BTREE p;
- int i, j, n;
- n=1;
- forest[0]=T;
- for(i=0; i<n; i++) //第一遍循环,把根的右子树、右子树的右子树....全放进数组
- {
- if(forest[i]->rchild)
- {
- forest[n++]=forest[i]->rchild;
- forest[i]->rchild=NULL;
- }//把右儿子切掉放在数组里
- }
- for(j=0; j<n; j++) //第二遍循环,把数组中每个元素的左子树的右子树、左子树的左子树的右子树...放进数组
- {
- p=forest[j]->lchild;
- while(p)
- {
- if(p->rchild!=NULL )
- {
- forest[n++]=p->rchild;
- }
- p=p->lchild;
- }
- }
- return n;
- }
- int main()
- {
- //ABDH##I##E##CF#J##G##
- BTREE tree, p;
- int n, i;
- BTREE forest[100];//存放转化为森林后的各个树根
- printf("请桉先根顺序输入二叉树(用#表示子树不存在):\n");
- CreateBT(tree);
- /*
- printf("\n先根遍历的结果为:\n");
- PreOrder(tree);
- printf("\n\n后根遍历的结果为:\n");
- PostOrder(tree);
- printf("\n按层遍历的结果为:\n");
- Level(tree);
- printf("\n\n转换为森林的结果为:\n");
- n=TreeToForest(tree, forest);
- for(i=0;i<n;i++)
- {
- printf("\n第%d棵树的根节点为: %c", i+1, forest[i]->data);
- if(forest[i]->lchild)
- {
- printf("\n 它的子节点元素为:");
- p=forest[i]->lchild;}
- else{printf(" (无儿子)");}
- while(p)
- {
- printf(" %c", p->data);
- p=p->lchild;
- }
- printf("\n");
- }
- getchar();
- return 0;
- }