線索化樹

#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();
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章