二叉樹的輸入輸出操做

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;
相關文章
相關標籤/搜索