二叉树的抽象数据类型

一、二叉树的抽象数据类型:
 

ADT BinaryTree{ 

 //数据对象D:D是具有相同特性的数据元素的集合。 
 //数据关系R: 
 //  若D=Φ,则R=Φ,称BinaryTree为空二叉树; 
 //  若D≠Φ,则R={H},H是如下二元关系; 
 //    (1)在D中存在惟一的称为根的数据元素root,它在关系H下无前驱; 
 //    (2)若D-{root}≠Φ,则存在D-{root}={D1,Dr},且D1∩Dr =Φ; 
 //    (3)若D1≠Φ,则D1中存在惟一的元素x1,<root,x1>∈H,且存在D1上的关系H1 ⊆H;若Dr≠Φ,则Dr中存在惟一的元素xr,<root,xr>∈H,且存在上的关系Hr ⊆H;H={<root,x1>,<root,xr>,H1,Hr}; 
 //    (4)(D1,{H1})是一棵符合本定义的二叉树,称为根的左子树;(Dr,{Hr})是一棵符合本定义的二叉树,称为根的右子树。 

 

 //基本操作: 
   InitBiTree( &T ) 
     //操作结果:构造空二叉树T。

   DestroyBiTree( &T ) 
   //  初始条件:二叉树T已存在。 
   //  操作结果:销毁二叉树T。 

   CreateBiTree( &T, definition ) 
   //  初始条件:definition给出二叉树T的定义。 
   //  操作结果:按definiton构造二叉树T。 

   ClearBiTree( &T ) 
   //  初始条件:二叉树T存在。 
   //  操作结果:将二叉树T清为空树。 

   BiTreeEmpty( T ) 
   //  初始条件:二叉树T存在。 
   //  操作结果:若T为空二叉树,则返回TRUE,否则返回FALSE。 

   BiTreeDepth( T ) 
   //  初始条件:二叉树T存在。 
   //  操作结果:返回T的深度。 

   Root( T ) 
   //  初始条件:二叉树T存在。 
   //  操作结果:返回T的根。 

   Value( T, e ) 
   //  初始条件:二叉树T存在,e是T中某个结点。 
   //  操作结果:返回e的值。 

   Assign( T, &e, value ) 
   //  初始条件:二叉树T存在,e是T中某个结点。 
   //  操作结果:结点e赋值为value。 

   Parent( T, e ) 
   //  初始条件:二叉树T存在,e是T中某个结点。 
   //  操作结果:若e是T的非根结点,则返回它的双亲,否则返回“空”。 

   LeftChild( T, e ) 
   //  初始条件:二叉树T存在,e是T中某个结点。 
   //  操作结果:返回e的左孩子。若e无左孩子,则返回“空”。 

   RightChild( T, e ) 
   //  初始条件:二叉树T存在,e是T中某个结点。 
   //  操作结果:返回e的右孩子。若e无右孩子,则返回“空”。 

   LeftSibling( T, e ) 
   //  初始条件:二叉树T存在,e是T中某个结点。 
   //  操作结果:返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回“空”。 

   RightSibling( T, e ) 
   //  初始条件:二叉树T存在,e是T中某个结点。 
   //  操作结果:返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回“空”。 

   InsertChild( T, p, LR, c ) 
   //  初始条件:二叉树T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T不相交且右子树为空。 
   //  操作结果:根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树。 

   DeleteChild( T, p, LR ) 
   //  初始条件:二叉树T存在,p指向T中某个结点,LR为0或1。 
   //  操作结果:根据LR为0或1,删除T中p所指结点的左或右子树。 

   PreOrderTraverse( T, visit() ) 
   //  初始条件:二叉树T存在,Visit是对结点操作的应用函数。 
   //  操作结果:先序遍历T,对每个结点调用函数Visit一次且仅一次。一旦visit()失败,则操作失败。 

   InOrderTraverse( T, visit() ) 
   //  初始条件:二叉树T存在,Visit是对结点操作的应用函数。 
   //  操作结果:中序遍历T,对每个结点调用函数Visit一次且仅一次。一旦visit()失败,则操作失败。 

   PostOrderTraverse( T, visit() ) 
   //  初始条件:二叉树T存在,Visit是对结点操作的应用函数。 
   //  操作结果:后序遍历T,对每个结点调用函数Visit一次且仅一次。一旦visit()失败,则操作失败。 

   LevelOrderTraverse( T, visit() ) 
   //  初始条件:二叉树T存在,Visit是对结点操作的应用函数。 
   //  操作结果:层次遍历T,对每个结点调用函数Visit一次且仅一次。一旦visit()失败,则操作失败。 

}ADT BinaryTree
 
//
//二、基本操作的实现:
//二叉树的结点结构体:

typedef struct{ 

    TElemType data; 

    struct BiTNode *lchild,*rchild; 

}BiTNode,*BiTree;

//二叉树的创建:

 /*******************************************/
 /*          按照前序遍历建立二叉树         */
 /*******************************************/
 Status CreateBiTree(BiTree &T) 
 { 
     //按先序次序输入二叉树中结点的值(一个字符), 
     //空格字符表示空树,构造二叉链表表示的二叉树T。 
     char ch; 
     ch = getchar();//scanf("%c",&ch); 
     if(ch == ' ') 
         T = NULL; 
     else
     { 
         if(!(T = (BiTNode*)malloc(sizeof(BiTNode)))) 
             exit(OVERFLOW); 
         T->data = ch;                //生成根结点 
         CreateBiTree(T->lchild);     //构造左子树 
         CreateBiTree(T->rchild);     //构造右子树 
     } 
     return OK; 
 }

 /************************************************************/
 /*                  按层次顺序建立一棵二叉树 :队列         */
 /************************************************************/
 Status LevelCreateBiTree(BiTree &T) 
 { 
     BiTree p,s;//p指向父亲结点,s指向孩子结点 
     Queue BiNodeQueue; 
     char ch; 
     ch=getchar(); 
     if(ch==' ') 
     { 
         return NULL; 
     } 
     T=(BiTNode*)malloc(sizeof(BiTNode)); //生成根结点 
     T->data=ch; 
     EnQueue(BiNodeQueue,T); //用队列实现层次遍历 
     while(!BiNodeQueue.Empty()) 
     { 
         DeQueue(BiNodeQueue,p); 
         ch=getchar(); //为了简化操作,分别对左右子结点进行赋值。 
         if(ch!=' ')//子树不空则进队列进行扩充。下同 
         { 
             s=(BiTNode*)malloc(sizeof(BiTNode)); 
             s->data=ch; 
             p->lchild=s; 
             EnQueue(BiNodeQueue,s); 
         } 
         else
         { 
             p->lchild=NULL; 
         } 
         ch=getchar(); 
         if(ch!=' ') 
         { 
             s=(BiTNode*)malloc(sizeof(BiTNode)); 
             s->data=ch; 
             p->rchild=s; 
             EnQueue(BiNodeQueue,s); 
         } 
         else
         { 
             p->rchild=NULL; 
         } 
     } 
     return OK; 
 }


//2.二叉树的前序遍历:

 /*******************************************/
 /*          按照前序递归遍历二叉树         */
 /*******************************************/
 Status PreOrderTraverse(BiTree T) 
 { 
     if(T) 
     { 
         printf("%d",T->data);   
         PreOrderTraverse(T->lchild);   
         PreOrderTraverse(T->rchild);  
     } 
     return OK; 
 }

 /*******************************************/
 /*          按照前序非递归遍历二叉树:栈   */
 /*******************************************/  
 Status PreOrderTraverse(BiTree T) 
 { 
     stack S; 
     InitStack(S);  
     BiTree p=T;  //p指向当前访问的结点 
     while(p||!StackEmpty(S)) 
     { 
         if(p) 
         { 
             printf("%c",p->data); 
             Push(S,p); 
             p=p->lchild; 
         } 
         else
         { 
             Pop(S,p); 
             p=p->rchild; 
         } 
     } 
     return OK; 
 }

 //3.二叉树的中序遍历:

 /*******************************************/
 /*          按照中序递归遍历二叉树         */
 /*******************************************/
 Status InOrderTraverse(BiTree T) 
 { 
     if(T) 
     { 
         InOrderTraverse(T->lchild); 
         printf("%d",T->data);  
         InOrderTraverse(T->rchild); 
     } 
     return OK; 
 }

 /*******************************************/
 /*          按照中序非递归遍历二叉树       */
 /*******************************************/
 Status InOrderTraverse(BiTree T)  
 {   
     stack S; 
     BiTree p; 
     InitStack(S);  Push(S, T);   
     while (!StackEmpty(S))  
     { 
         while (GetTop(S, p) && p)  
             Push(S, p->lchild);   // 向左走到尽头 
         Pop(S, p);                // 空指针退栈(叶子的左孩子) 
         if (!StackEmpty(S))  
         {   // 访问结点,向右一步 
             Pop(S, p);   
             printf("%d",p->data);   //当前根结点 
             Push(S, p->rchild); 
         } 
     } 
     return OK; 
 }

 /*******************************************/
 /*          按照中序非递归遍历二叉树       */
 /*******************************************/
 Status InOrderTraverse(BiTree T)  
 {   
     stack S; 
     InitStack(S); 
     BiTree p=T;   
     while (p || !StackEmpty(S))  
     { 
         if (p)  
         {  
             Push(S, p);   
             p = p->lchild;  
         }  // 非空指针进栈,继续左进 
         else 
         {  // 上层指针退栈,访问其所指结点,再向右进 
             Pop(S, p);   
             printf("%d",p->data);  
             p = p->rchild; 
         } 
     } 
     return OK; 
 }

 //二叉树的后序遍历:
 /*******************************************/
 /*          按照后序递归遍历二叉树         */
 /*******************************************/
 Status PostOrderTraverse(BiTree T) 
 { 
     if(T) 
     { 
         PostOrderTraverse(T->lchild); 
         PostOrderTraverse(T->rchild); 
         printf("%d",T->data); 
     } 
     return OK; 
 }

 /*******************************************/
 /*        按照后序非递归遍历二叉树         */
 /*******************************************/
 Status PostOrderTraverse(BiTree T)  
 {  
     stack S; 
     InitStack(S); 
     BiTree p=T,pre=NULL; 
     while ( p || !StackEmpty(S))  
     {  
         if (p)  
         {  
             Push(S,p);  
             p = p->left;  
         }  
         else 
         {  
             Pop(S,p);  
             if (p->right!=NULL && pre!=p->right) 
             { //pre指向上次访问的右结点,避免再次访问 
                 p=p->right;  
             }  
             else
             {  
                 printf("%d",p->data); 
                 pre=p; 
                 p=NULL;  
             }  
         }  
     }  
}

 /*******************************************/
 /*        按照后序非递归遍历二叉树         */
 /*******************************************/
 Status PostOrderTraverse(BiTree T)  
 { 
     BiTree p = T,last = NULL; 
     stack S; 
     InitStack(S); 
     Push(S,p); 
     while(!StackEmpty(S)) 
     { 
         Pop(S,p); 
         if(last == p->left || last == p->right)//左右子树已经访问完了,该访问根节点了 
         { 
             printf("%d",p->data); 
             last = p; 
         } 
         else if(p->left || p->right) //左右子树未访问,当前节点入栈,左右节点入栈 
         { 
             Push(S,p); 
             if(p->right) 
                 Push(S,p->right); 
             if(p->left) 
                 Push(S,p->left); 
         } 
         else //当前节点为叶节点,访问 
         { 
             printf("%d",p->data); 
             last = p; 
         } 
     } 
 }

 

 

 //二叉树的层次遍历:
 /*******************************************/
 /*           按照层次遍历二叉树            */
 /*******************************************/
 void LevelOrderTraverse(BiTree T) 
 { 
     Queue BiNodeQueue; 
     BiTree p=T; 
     EnQueue(BiNodeQueue,p); 
     while(!BiNodeQueue.Empty()) 
     { 
         DeQueue(BiNodeQueue,p); 
         if(p) 
         { 
             printf("%c",p->data); 
             EnQueue(BiNodeQueue,p->lchild); 
             EnQueue(BiNodeQueue,p->rchild); 
         } 
     } 
 }

 //交换左右子树:

 /*******************************************/
 /*      递归法将二叉树的左右子树互换       */
 /*******************************************/
 void Exchange(BiTree T) 
 { 
     BiTree temp; 
     if(T) 
     { 
         Exchange1(T->lchild); 
         Exchange1(T->rchild); 
         temp=T->lchild; 
         T->lchild=T->rchild; 
         T->rchild=temp; 
     } 
 }

 /*******************************************/
 /*      非递归法将二叉树的左右子树互换     */
 /*******************************************/
 void Exchange(BiTree T) 
 { 
     stack S; 
     InitStack(S); 
     BiTree p=T,temp; 
     while(p||!StackEmpty(S)) 
     { 
         if(p) 
         { 
             Push(S,p); 
             temp=p->lchild; 
             p->lchild=p->rchild; 
             p->rchild=temp; 
             p=p->lchild; 
         } 
         else
         { 
             Pop(S,p); 
             p->rchild; 
         } 
     } 
 }

 

 //7.统计二叉树中叶子结点的数目:

 /*******************************************/
 /*        递归法求叶子结点个数             */
 /*******************************************/
 int LeavesNum(BiTree T) 
 { 
     if(T) 
     { 
         if(T->lchild==NULL&&T->rchild==NULL) 
         { 
             return 1; 
         } 
         return LeavesNum(T->lchild)+LeavesNum(T->rchild); 
     } 
     return 0; 
 }

 /*******************************************/
 /*        非递归法求叶子结点个数           */
 /*******************************************/
 int LeavesNum(BiTree T) 
 { 
     int count=0; 
     stack S; 
     InitStack(S); 
     BiTree p=T; 
     while(p||!StackEmpty(S)) 
     { 
         if(p) 
         { 
             Push(S,p); 
             if(p->lchild==NULL&&p->rchild==NULL) 
             { 
                 count++; 
             } 
             p=p->lchild; 
         } 
         else
         { 
             Pop(S,p); 
             p=p->rchild; 
         } 
     } 
     return count; 
 }

 

 

 //8.求二叉树的深度:
 /**********************************************/
 /*                  求一棵树的高度            */
 /**********************************************/
 int Depth(BiTree T) 
 {
     int  lh = rh =0 ; 
     BiTree p=T; 
     if(p==NULL) 
     { 
         return 0 ; 
     } 
     else
     { 
         lh = Depth( p->lchild ) ; 
         rh = Depth( p->rchild ) ; 
         return ( lh > rh ? lh : rh ) + 1 ; 
     } 
  }
 
 
   //9.判断两棵树是否等价:
   /*******************************************************/
   /*                  判断两棵是否等价                   */
   /*******************************************************/
   int Is_equal( BiTree T1 , BiTree T2 ) 
 { 
     int t=0; 
     if(NULL == T1 && NULL == T2) 
     { 
         t=1; 
     } 
     else
     { 
         if(NULL !=T1 &&NULL != T2 ) 
         { 
             if(T1->data == T2->data) 
             { 
                 if(Is_equal(T1->lchild,T2->lchild)) 
                 { 
                     t=Is_equal(T1->rchild,T2->rchild); 
                 } 
             } 
         } 
     } 
     return t; 
 }


 //10.查找某个信息是否在这棵树中
 /****************************************************/
 /*            查找某个信息是否在这棵树中            */
 /****************************************************/
 BiTree Locate(BiTree T,char x) 
 { 
     BiTree p=T; 
     if(P==NULL)  
         return NULL; 
     else
     { 
         if( P -> data == x )  
             return P; 
         else
         { 
             p = Locate(P->lchild,x); 
             if(p) 
                 return p; 
             else
                 return Locate(P->rchild,x); 
         } 
     } 
 }


 //11.结点个数:
 /****************************************************/
 /*                  树的结点个数                    */
 /****************************************************/
 int  Num_Of_Node(BiTree t) 
 { 
     if(t==NULL) 
         return 0 ; 
     else 
         return Num_Of_Node(t->lchild)+Num_Of_Node(t->rchild)+1; 
 }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值