线索化树

#include "stdio.h"
#include "stdlib.h"
#define LEFT 1
#define RIGHT 2
#define MAX 20
/**************************************
 定义树的结构体
***************************************/
typedef struct tagtree
{
 char data;                /*数据域*/
 int ltag;                 /*线索化时用来标志是左孩子还是前驱*/
 int rtag;                 /*线索化时用来标志是右孩子还是后继*/
 struct tagtree*lchild;    /*指向左孩子的指针域*/
 struct tagtree*rchild;    /*指向右孩子的指针域*/
}tree;

tree *pre=NULL;            /*全局指针,线索化时用来保存前一个结点*/
/****************************************
  创建一棵树,要求这棵树用括号表示法输入
*****************************************/
void CreateTree(tree **root,char *str)
{
 char ch;
 tree *stack[MAX],*lp=NULL,*temp;      /*定义一个指向树的一个栈,
                                    用来创建其结点的父子关系*/
 int top=-1,flag;              /*指向树栈的栈顶,flag用来标记左右孩子*/
 (*root)=NULL;                 /*特别注意这里一定要先将指向根结点的指针附空,否则
                                   在XP系统下就会出大错*/
while((*str)!='/0')
{
 ch=(*str);
 switch(ch)
 {
  case '(':                 /*下去的DATA值将作为栈顶结点的左右孩子*/
           top++;
	   stack[top] = lp; /*将双亲结点入栈*/
           flag = LEFT;     /*标记其下一个结点将作为此栈顶结点的
                               左孩子*/
           break;
  case ',':
           flag = RIGHT;    /*标记为下去结点将作为此栈顶结点的
                               右孩子*/
           break;
  case ')':
           top--;           /*将栈顶结点退栈,这样才能保证双亲及
                               其对应孩子的正确配对*/
           break;

  default:                  /*此时CH为DATA域*/
           lp = (tree*)malloc(sizeof(tree)); /*创建一个结点*/
           lp->data = ch;
           lp->lchild = NULL;
           lp->rchild = NULL;
           if((*root) == NULL)       /*是树的根结点*/
             (*root) = lp;
           else
           {
                  /*注意此处不能用这种表达方式*/
                 /* temp = (flag == LEFT) ? stack[top]->lchild : stack[top]->rchild;
                  temp = lp;  */

                 switch(flag)
                  {
                    case RIGHT:                           /*插到右结点*/
                                stack[top]->rchild = lp;
                                 break;
                    case LEFT:                           /*插到左结点*/
                                 stack[top]->lchild = lp;
                                  break;
                     }
               }
          break;
   }
   str++;
}
}
/************************************************
 用树形表示法输出树
*************************************************/
void DispTree(tree *root,int x,int y,int n)     /*n用来控制第一层树的高度*/
{
 int i=0;
 if(root !=NULL)
  {
    gotoxy(x,y);                               /*到相应结点输出*/
    printf("%c",root->data);
    if(root->lchild != NULL)                  /*处理左子树,这里只有第一次N为可变的,*/
    {
       i=1;                                   /*为的是能够输出整棵树,而不会被覆盖,*/
       while(ilchild,x-n,y+n,2);       /*递归处理左子树*/
     }
     if(root->rchild != NULL)
    {
       i=1;
       while(irchild,x+n,y+n,2);       /*递归处理右子树*/
     }
   }
}

/******************************************************
 对一棵树进行中序线索化
********************************************************/
void inthread(tree*root)
{
 if(root!=NULL)
 {
   inthread(root->lchild);                  /*先线索化左孩子*/
   if(root->lchild ==NULL)                         /*线索化根结点*/
   {
     root->lchild=pre;
     root->ltag=1;                          /*ltag=1表示指向的是前驱*/
   }
   else  root->ltag=0;
   if(pre!=NULL)                           /*注意这里要加个判断,否则在第一个时pre==NULL*/
   {                                       /*编译出错,NULL POINTER ASSGINED*/
       if(pre->rchild == NULL)
       {
         pre->rchild=root;
         pre->rtag=1;                /*rtag=1表示指向的是后继*/
       }
       else pre->rtag=0;
   }
   pre=root;
   inthread(root->rchild);       /*最后线索化左孩子*/
 }
}

/***************************************************
 访问中序线索树中的每一个结点
****************************************************/
void VsInthread(tree*root)
{
 tree*lp;
 if(root!=NULL)
 {
  while(root->ltag==0)        /*有左孩子,继续查找左孩子*/
       root=root->lchild;
  printf("%c ",root->data); 
  while(root->rchild !=NULL)
 {  
   if(root->rtag==1)
     root=root->rchild;         /*直接访问后续结点*/
   else
      {
        root=root->rchild;     /*ROOT有右孩子,要找到右孩子的左孩子*/
        while(root->ltag == 0)
             root=root->lchild;
      }
   printf("%c ",root->data);
  }
 }
}
  
 


void main()
{
 char str[20];
 tree*root=NULL;
 printf("Input the str:");
 gets(str);
 CreateTree(&root,str);
 printf("the result is:");
 DispTree(root,10,4,5);
 getch();
 inthread(root);
 printf("/n/nthe thread visit result is:");
 VsInthread(root);
 getch();
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章