樹相關操作的遞歸算法實現

/****************************************************************
* 
* 文件名:Rstree.c 
* 
* 文件描述:樹相關操作的遞歸算法實現 
* 
* 創建人:顏清國 2006年4月15日 
* 
* 
* 修改記錄: 
* 
**************************************************************/ 
#include "stdio.h"
#include"stdlib.h"
#include"conio.h"
#define LEFT 1
#define RIGHT 2
#define MAX 20

/**************************************
 定義樹的結構體
***************************************/
typedef struct tagtree
{
 char data;                /*數據域*/
 int flag;                 /*非遞歸操作時用來做標誌*/
 struct tagtree*lchild;    /*指向左孩子的指針域*/
 struct tagtree*rchild;    /*指向右孩子的指針域*/
}tree;


/****************************************
  創建一棵樹,要求這棵樹用括號表示法輸入
*****************************************/
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 OutTree(tree *root)
{
 if(root != NULL)
 {
  printf("%c",root->data);       /*先輸出根結點*/
  if(root->lchild != NULL || root->rchild != NULL)
  {
   printf("(");
   OutTree(root->lchild);        /*處理左子樹*/
   if(root->rchild != NULL)
   {
    printf(",");
   }
  OutTree(root->rchild);         /*處理右子樹*/
  printf(")");
}
}
}



/************************************************
 遞歸先序遍歷二叉樹
************************************************/
void RsPrePath(tree *root)
{
 if(root!=NULL)
 {
   printf("%c ",root->data);         /*遇到根結點先輸出*/
   RsPrePath(root->lchild);            /*遇到根結點左子數先輸出,
                                       直到空,返回是輸出左子數
                                       根結點右子數*/
   RsPrePath(root->rchild);            /*同樣處理右子數*/
 }
}




/************************************************
 遞歸中序遍歷二叉樹
************************************************/
void RsMidPath(tree *root)
{
 if(root!=NULL)
 {
   RsMidPath(root->lchild);
   printf("%c ",root->data);
   RsMidPath(root->rchild);
 }
}



/************************************************
 遞歸後序遍歷二叉樹
************************************************/
void RsLastPath(tree *root)
{
 if(root!=NULL)
 {
   RsLastPath(root->lchild);
   RsLastPath(root->rchild);
   printf("%c ",root->data);
 }
}




/***********************************************
 遞歸遍歷二叉樹演示
************************************************/
void RsTreeDemo(tree*root)
{
 printf("/nthe PrePath is:");
 RsPrePath(root);
 printf("/nthe MidPath is:");
 RsMidPath(root);
 printf("/nthe LastPath is:");
 RsLastPath(root);
}

/************************************************
 用樹形表示法輸出樹
*************************************************/
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);       /*遞歸處理右子樹*/
     }
   }
}


/*****************************************************
 根據DATA域,查找第一個遇到的結點,並返回該結點
 *****************************************************/
tree* IndexNode(tree *root,char data,int *high,int temp)
{
 if(root == NULL)
 {
    (*high)=0;
    return NULL;
 }
 else
       if(root->data == data)  /*找到所要找的結點*/
       {
           (*high) = temp;
           return root;
       }
       else
       {
	   if(IndexNode(root->lchild,data,high,temp+1)==NULL)
           {
	      IndexNode(root->rchild,data,high,temp+1);/*如果在左

子樹中沒有找到*/
           }
       }
}




/****************************************************
 找某一結點的左子樹
 ****************************************************/
tree* FindLchild(tree * node)
{
  if(node !=NULL)
  {
       return node->lchild;
  }
  else
        return NULL;
}



/****************************************************
 找某一結點的右子樹
 ****************************************************/
tree* FindRchild(tree * node)
{
if(node !=NULL)
  {
       return node->rchild;
  }
  else
        return NULL;
}


/****************************************************
 先序遍歷查找所有葉子結點
 ****************************************************/
void FindLeaft(tree *root)
{
 if(root == NULL)
    return;
 if(root->lchild == NULL && root->rchild == NULL)
 {
    printf("%c ",root->data);
 }
 FindLeaft(root->lchild);
 FindLeaft(root->rchild);
}




void main()
{
 tree *root;
 int high;
 char str[100];
 clrscr();
 printf("Please  input the Tree string:");
 gets(str);
 CreateTree(&root,str);
 printf("/nthe Tree is:");
 DispTree(root,10,4,5);
 gotoxy(2,15);
 FindLeaft(root);
 /*printf("/n%c",IndexNode(root,'t',&high,1)->data);
 printf("/n%d",high);*/
 /*RsTreeDemo(root);*/
 getch();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章