二叉树的输入输出操做

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

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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,且存在Dr上的关系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

 

 

2、基本操做的实现:

二叉树的结点结构体:函数

 

1
2
3
4
typedef  struct {
     TElemType data;
     struct  BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

 

 

1.二叉树的建立:spa

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*******************************************/
/*          按照前序遍历创建二叉树         */
/*******************************************/
 
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;
}

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/************************************************************/
/*                  按层次顺序创建一棵二叉树 :队列         */
/************************************************************/
 
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.二叉树的前序遍历:指针

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*******************************************/
/*          按照前序递归遍历二叉树         */
/*******************************************/
 
Status PreOrderTraverse(BiTree T)
{
     if (T)
     {
         printf ( "%d" ,T->data); 
         PreOrderTraverse(T->lchild); 
         PreOrderTraverse(T->rchild);
     }
     return  OK;
}

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*******************************************/
/*          按照前序非递归遍历二叉树:栈   */
/*******************************************/
 
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.二叉树的中序遍历:code

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*******************************************/
/*          按照中序递归遍历二叉树         */
/*******************************************/
 
Status InOrderTraverse(BiTree T)
{
     if (T)
     {
         InOrderTraverse(T->lchild);
         printf ( "%d" ,T->data);
         InOrderTraverse(T->rchild);
     }
     return  OK;
}

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*******************************************/
/*          按照中序非递归遍历二叉树       */
/*******************************************/
 
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;
}

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*******************************************/
/*          按照中序非递归遍历二叉树       */
/*******************************************/
 
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;
}

 

 

4.二叉树的后序遍历:对象

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*******************************************/
/*          按照后序递归遍历二叉树         */
/*******************************************/
 
Status PostOrderTraverse(BiTree T)
{
     if (T)
     {
         PostOrderTraverse(T->lchild);
         PostOrderTraverse(T->rchild);
         printf ( "%d" ,T->data);
     }
     return  OK;
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*******************************************/
/*        按照后序非递归遍历二叉树         */
/*******************************************/
 
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;
             }
         }
     }
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*******************************************/
/*        按照后序非递归遍历二叉树         */
/*******************************************/
 
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;
         }
     }
}

 

 

5.二叉树的层次遍历:blog

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*******************************************/
/*           按照层次遍历二叉树            */
/*******************************************/
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);
         }
     }
}

 

6.交换左右子树:递归

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*******************************************/
/*      递归法将二叉树的左右子树互换       */
/*******************************************/
void  Exchange(BiTree T)
{
     BiTree temp;
     if (T)
     {
         Exchange1(T->lchild);
         Exchange1(T->rchild);
         temp=T->lchild;
         T->lchild=T->rchild;
         T->rchild=temp;
     }
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*******************************************/
/*      非递归法将二叉树的左右子树互换     */
/*******************************************/
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.统计二叉树中叶子结点的数目:队列

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*******************************************/
/*        递归法求叶子结点个数             */
/*******************************************/
int  LeavesNum(BiTree T)
{
     if (T)
     {
         if (T->lchild==NULL&&T->rchild==NULL)
         {
             return  1;
         }
         return  LeavesNum(T->lchild)+LeavesNum(T->rchild);
     }
     return  0;
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*******************************************/
/*        非递归法求叶子结点个数           */
/*******************************************/
int  LeavesNum(BiTree T)
{
     int  count=0;
     stack S;