anyview 數據結構習題集 第6章答案


6.33③ 假定用兩個一維數組L[1..n]和R[1..n]作為
有n個結點的二叉樹的存儲結構, L[i]和R[i]分別指
示結點i的左孩子和右孩子,0表示空。試寫一個算法
判別結點u是否為結點v的子孫。
要求實現以下函數:
Status Dencendant(Array1D L,Array1D R,int n,int u,int v);
/* If node ‘u’ is the dencendant of node ‘v’, */
/* then return ‘TRUE’ else return ‘FALSE’. */
/* L[i] is the left child of the i_th node, */
/* R[i] is the right child of the i_th node */
/* in the Binary Tree which has n nodes. */
一維數組類型Array1D的定義:
typedef int Array1D[MAXSIZE];

Status Dencendant (Array1D L,Array1D R, int n, int u, int v )  
/* If node 'u' is the dencendant of node 'v', */  
/* then return 'TRUE' else return 'FALSE'.    */  
/* L[i] is the left child of the i_th node,   */  
/* R[i] is the right child of the i_th node   */  
/* in the Binary Tree which has n nodes.      */  
{     
     int flag = 0 ;  
     if ( !v ) {  
         return FALSE ;  
     }  
     else {  
         if (L [v ] ==u ) {  
             return TRUE ;  
         }  
         else {  
            flag + =Dencendant (L,R,n,u,L [v ] ) ;  
         }  
         if (R [v ] ==u ) {  
             return TRUE ;  
         }  
         else {  
            flag + =Dencendant (L,R,n,u,R [v ] ) ;  
         }  
         if (flag ) {  
             return TRUE ;  
         }  
         return FALSE ;  
     }  
}

6.34③ 假定用兩個一維數組L[1..n]和R[1..n]作為
有n個結點的二叉樹的存儲結構, L[i]和R[i]分別指
示結點i的左孩子和右孩子,0表示空。試寫一個算法,
先由L和R建立一維數組T[1..n],使T中第i(i=1,2,…,
n)個分量指示結點i的雙親,然后判別結點u是否為結
點v的子孫。
要求實現以下函數:
Status Dencend(Array1D L, Array1D R, int n, int u, int v, Array1D T);
/******************************************************************/
一維數組類型Array1D的定義:
typedef int Array1D[MAXSIZE];

Status Dencend (Array1D L, Array1D R,  int n,  int u,  int v, Array1D T )  
/******************************************************************/  
{  
     int i,val ;  
     for (i = 1 ;i <=n ; ++i ) { //初始化數組T  
        T [i ] = 0 ;  
     }  
     for (i = 1 ;i <=n ; ++i ) { //建立數組T  
        T [L [i ] ] =i ;  
        T [R [i ] ] =i ;  
     }  
    val =T [u ] ;  
     while (val ! = 0 ) {  
         if (val ==v ) {  
             return TRUE ;  
         }  
        val =T [val ] ;  
     }  
     return FALSE ;  
}

6.36③ 若已知兩棵二叉樹B1和B2皆為空,或者皆
不空且B1的左、右子樹和B2的左、右子樹分別相似,
則稱二叉樹B1和B2相似。試編寫算法,判別給定兩
棵二叉樹是否相似。
要求實現下列函數:
Status Similar(BiTree t1, BiTree t2);
/* 判斷兩棵二叉樹是否相似的遞歸算法 */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

Status Similar (BiTree t1, BiTree t2 )  
/* 判斷兩棵二叉樹是否相似的遞歸算法 */  
{  
     if ( !t1 &&!t2 ) { //如果兩棵樹同為空  
         return TRUE ;  
     }  
     else  if (t1 &&t2 ) { //如果兩棵樹同為非空,則返回各個子樹的比較結果  
         return Similar (t1 - >lchild,t2 - >lchild ) &&Similar (t1 - >rchild,t2 - >rchild ) ;  
     }  
     else { //當兩棵樹存在不相似的時候時,即一棵為空,一棵非空  
         return FALSE ;  
     }      
}

6.37③ 試直接利用棧的基本操作寫出先序遍歷的非遞歸
形式的算法(提示:不必按3.3.2節介紹的從遞歸到非遞歸
的方法而直接寫出非遞歸算法)。
要求實現下列函數:
void PreOrder(BiTree bt, void (*visit)(TElemType));
/* 使用棧,非遞歸先序遍歷二叉樹bt, */
/* 對每個結點的元素域data調用函數visit */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用棧類型Stack的相關定義:
typedef BiTree SElemType; // 棧的元素類型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);

void PreOrder (BiTree bt,  void  ( *visit ) (TElemType ) )   
/* 使用棧,非遞歸先序遍歷二叉樹bt,    */  
/* 對每個結點的元素域data調用函數visit */  
{  
//基本思路:根據工作棧原理,模擬遞歸的效果~  
     if (bt ) { //判斷樹空  
       SElemType p =bt ;  
       Stack S ;      
       InitStack (S ) ;  
        while ( !StackEmpty (S ) ||p ) {   
             while (p ) { //先序訪問根節點、遍歷左節點  
                visit (p - >data ) ;  
                Push (S,p ) ;  
                p =p - >lchild ;  
             }  
             if ( !StackEmpty (S ) ) { //遍歷右節點,不小心寫成while,錯了幾次~~  
                Pop (S,p ) ;  
                p =p - >rchild ;  
             }       
        }          
     }  
}

6.38④ 同6.37題條件,寫出后序遍歷的非遞歸算法
(提示:為分辨后序遍歷時兩次進棧的不同返回點,
需在指針進棧時同時將一個標志進棧)。
要求實現下列函數:
void PostOrder(BiTree bt, void (*visit)(TElemType));
/* 使用棧,非遞歸后序遍歷二叉樹bt, */
/* 對每個結點的元素域data調用函數visit */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用棧類型Stack的相關定義:
typedef struct {
BiTNode *ptr; // 二叉樹結點的指針類型
int tag; // 0..1
} SElemType; // 棧的元素類型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);

void PostOrder (BiTree bt,  void  ( *visit ) (TElemType ) )  
/* 使用棧,非遞歸后序遍歷二叉樹bt,    */  
/* 對每個結點的元素域data調用函數visit */  
{    
    Stack S ;  
    InitStack (S ) ;  
    SElemType e ;  
    BiTree p =bt ;  
     int tag = 0 ;  
     if (bt ) {  
        e. tag = 0 ;  
         while ( !StackEmpty (S ) ||p ==bt ) {  
             while (p &&!tag ) {  
                e. ptr =p ;  
                 if (p - >lchild ) { //如果存在左子樹  
                    p =p - >lchild ;  
                    e. tag = 0 ;  
                 }  
                 else { //否則為右子樹   
                    p =p - >rchild ;  
                    e. tag = 1 ;  
                 }   
                Push (S,e ) ;  
             } //while  
            GetTop (S,e ) ;  
             if ( !StackEmpty (S ) &&e. tag ) {  
                Pop (S,e ) ;  //葉子結點出棧  
                p =e. ptr ;  
                visit (p - >data ) ; //輸出該結點  
             }             
             if ( !StackEmpty (S ) ) {  
                Pop (S,e ) ;  //得到上一層結點  
                p =e. ptr ;              
                 if (e. tag ) { //右子樹已經入棧  
                    visit (p - >data ) ;  
                    p = NULL ;  
                 }  
                 else { //右子樹沒入過棧  
                     if (p - >rchild ) {  
                        p =p - >rchild ;  
                        tag = 0 ;  
                        e. tag = 1 ;  
                        Push (S,e ) ;  
                     }  
                     else  { //沒有右子樹  
                        visit (p - >data ) ;  
                        p = NULL ;                          
                     }  
                 }          
             }  
             else { //棧空則,p為NULL  
                p = NULL ;  
             }  
          } //while  
     } //if  
}

6.41③ 編寫遞歸算法,在二叉樹中求位於先序序列中
第k個位置的結點的值。
要求實現下列函數:
TElemType PreOrder(BiTree bt, int k);
/* bt is the root node of a binary linked list, */
/* Preorder travel it and find the node whose */
/* position number is k, and return its value. */
/* if can’t found it, then return ‘#’. */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

TElemType Get (BiTree bt, int  &count,TElemType  &e ) {  
     if (bt ) {  
         if ( 1 ==count ) {  
            e =bt - >data ;  
             return  0 ;  
         }  
         else {  
             if (bt - >lchild ) {  
                 --count ;  
                Get (bt - >lchild,count,e ) ;  
             }  
             if (bt - >rchild ) {  
                 --count ;  
                Get (bt - >rchild,count,e ) ;  
             }                  
         }  
     }  
}  
//沒想到可以自己添加函數~~方便很多  
TElemType PreOrder (BiTree bt,  int k )  
/* bt is the root node of a binary linked list, */  
/* Preorder travel it and find the node whose   */  
/* position number is k, and return its value.  */  
/* if can't found it, then return '#'.          */  
{   
    TElemType e ;  
    e = '#' ;  
    Get (bt,k,e ) ;  
     return  e ;  
}

6.42③ 編寫遞歸算法,計算二叉樹中葉子結點的數目。
要求實現下列函數:
void Leaves(BiTree bt, int &x);
/* Count the leaf node of the BiTree */
/* whose root node is bt to x. */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

void Leaves (BiTree bt,  int  &x )  
/* Count the leaf node of the BiTree */  
/* whose root node is bt to x.       */  
//題目並沒有說x初始化為0,害人不淺啊~~  
{  
     int l1,l2 ;  
     if (bt ) {  
         if ( !bt - >lchild &&!bt - >rchild ) {  
             ++x ;  
         }  
         else {  
            Leaves (bt - >lchild,x ) ;  
            Leaves (bt - >rchild,x ) ;  
         }  
     }          
}

6.43③ 編寫遞歸算法,將二叉樹中所有結點的
左、右子樹相互交換。
要求實現下列函數:
void Exchange(BiTree &bt);
/* Exchange the left and right leaves of */
/* bitree whose root node is bt */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

void Exchange (BiTree  &bt )  
/* Exchange the left and right leaves of */  
/* bitree whose root node is bt          */  
{  
    BiTree temp ;  
     if (bt ) {  
            Exchange (bt - >lchild ) ;  
            Exchange (bt - >rchild ) ;  
            temp =bt - >lchild ;  
            bt - >lchild =bt - >rchild ;  
            bt - >rchild =temp ;  
     }      
}

6.44④ 編寫遞歸算法:求二叉樹中以元素值
為x的結點為根的子樹的深度。
要求實現下列函數:
int Depthx(BiTree T, TElemType x);
/* 求二叉樹中以值為x的結點為根的子樹深度 */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

int Depth (BiTree T ) {  
     int l1,l2 ;  
     if ( !T ) {  
         return  0 ;  
     }  
     else {  
        l1 =Depth (T - >lchild ) + 1 ;  
        l2 =Depth (T - >rchild ) + 1 ;  
         return  (l1 >l2 ) ?l1 :l2 ;  
     }      
}  
int Findx (BiTree T,BiTree  &p,TElemType x ) {  
     if (T ) {  
         if (T - >data ==x ) {  
            p =T ;  
             return  0 ;  
         }  
         else {  
            Findx (T - >lchild,p,x ) ;  
            Findx (T - >rchild,p,x ) ;  
         }      
     }  
}  
int Depthx (BiTree T, TElemType x )  
/* 求二叉樹中以值為x的結點為根的子樹深度 */  
{  
    BiTree p = NULL ;  
    Findx (T,p,x ) ;  
     return Depth (p ) ;      
}

6.46③ 編寫復制一棵二叉樹的非遞歸算法。
要求實現下列函數:
void CopyBiTree(BiTree T, BiTree &TT);
/* 基於層次遍歷的非遞歸復制二叉鏈表 */
二叉鏈表類型定義:
typedef char TElemType; // 設二叉樹的元素為char類型
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
可用隊列類型Queue的相關定義:
typedef BiTree QElemType; // 設隊列元素為二叉樹的指針類型
Status InitQueue(Queue &Q);
Status EnQueue(Queue &Q, QElemType e);
Status DeQueue(Queue &Q, QElemType &e);
Status GetHead(Queue Q, QElemType &e);
Status QueueEmpty(Queue Q);

void CopyBiTree (BiTree T, BiTree  &TT )  
/* 基於層次遍歷的非遞歸復制二叉鏈表 */  
//基本思想:用兩個隊列來同步操作!  
{  
    BiTree p,p2 ;  
    Queue Q,Q2 ;  
     if ( !T ) {  
        TT = NULL ;  
         return ;   
     }  
    TT = (BiTree ) malloc ( sizeof (BiTNode ) ) ;  
    InitQueue (Q ) ;  
    InitQueue (Q2 ) ;  
    EnQueue (Q,T ) ;      
    EnQueue (Q2,TT ) ;  
     while ( !QueueEmpty (Q ) ) {  
        DeQueue (Q,p ) ;  
        DeQueue (Q2,p2 ) ;  
        p2 - >data =p - >data ;  
         if (p - >lchild ) {  
            EnQueue (Q,p - >lchild ) ;  
            p2 - >lchild = (BiTree ) malloc ( sizeof (BiTNode ) ) ;  
             if ( !p2 - >lchild ) {  
                 exit (OVERFLOW ) ;  
             }  
            EnQueue (Q2,p2 - >lchild ) ;  
         }  
         else {  
            p2 - >lchild = NULL ;  
         }  
         if (p - >rchild ) {              
            EnQueue (Q,p - >rchild ) ;  
            p2 - >rchild = (BiTree ) malloc ( sizeof (BiTNode ) ) ;  
             if ( !p2 - >rchild ) {  
                 exit (OVERFLOW ) ;  
             }  
            EnQueue (Q2,p2 - >rchild ) ;  
         }  
         else {  
            p2 - >rchild = NULL ;  
         }                  
     }  
}

6.47④ 編寫按層次順序(同一層自左至右)遍歷二叉樹的算法。
要求實現下列函數:
void LevelOrder(BiTree bt, char *ss);
/* travel BiTree bt by level, Return result by ss. */
二叉鏈表類型定義:
typedef char TElemType; // 設二叉樹的元素為char類型
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
可用隊列類型Queue的相關定義:
typedef BiTree QElemType; // 設隊列元素為二叉樹的指針類型
Status InitQueue(Queue &Q);
Status EnQueue(Queue &Q, QElemType e);
Status DeQueue(Queue &Q, QElemType &e);
Status GetHead(Queue Q, QElemType &e);
Status QueueEmpty(Queue Q);
提示:可將遍歷元素的值(字符)依次置入ss,並最后以’\0′結尾。
也可以用下列字符串函數產生ss:
int sprintf(char *buffer, char *format [, argument, ...]);
char *strcat(char *dest, char *src);

void LevelOrder (BiTree bt,  char  *ss )  
/* travel BiTree bt by level, Return result by ss. */  
{  
     int i = 0 ;  
    Queue Q ;  
    BiTree p ;  
    InitQueue (Q ) ;  
     if (bt ) {  
        EnQueue (Q,bt ) ;  
         while ( !QueueEmpty (Q ) ) {  
            DeQueue (Q,p ) ;  
            ss [i ++ ] =p - >data ;  
             if (p - >lchild ) {  
                EnQueue (Q,p - >lchild ) ;  
             }  
             if (p - >rchild ) {  
                EnQueue (Q,p - >rchild ) ;  
             }              
         }  
        ss [i ] = '\0' ;  
     }  
}

6.49④ 編寫算法判別給定二叉樹是否為完全二叉樹。
要求實現下列函數:
Status CompleteBiTree(BiTree bt);
/* judge if the binary tree whose root is bt */
/* is a complete tree. */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
可用隊列類型Queue的相關定義:
typedef BiTree QElemType; // 設隊列元素為二叉樹的指針類型
Status InitQueue(Queue &Q);
Status EnQueue(Queue &Q, QElemType e);
Status DeQueue(Queue &Q, QElemType &e);
Status GetHead(Queue Q, QElemType &e);
Status QueueEmpty(Queue Q);

Status CompleteBiTree (BiTree bt )  
/* judge if the binary tree whose root is bt */  
/*  is a complete tree.                      */  
/*基本思路 
使用一個棧記錄按層次遍歷結果,當該結點非NULL時,左右子樹入棧 
因此,如果該樹為完全二叉樹時棧內容為XXXX##(X表示非空),##之間不可能有非空結點 
如果非完全二叉樹則內容可能為XXX#XX##也就是在NULL結點間仍有非空結點 
只要非空結點與空結點分布情況即可求解 
*/
  
{  
     int flag = 0,top = 0 ;  
    BiTree stack [ 100 ] ;  
    Queue Q ;  
    BiTree p ;  
    InitQueue (Q ) ;  
     if (bt ) {  
        EnQueue (Q,bt ) ;  
         while ( !QueueEmpty (Q ) ) {  
            DeQueue (Q,p ) ;  
             if (p ) {  
                EnQueue (Q,p - >lchild ) ;              
                EnQueue (Q,p - >rchild ) ;  
                stack [top ++ ] =p - >lchild ;  
                stack [top ++ ] =p - >rchild ;                  
             }                   
         } //while  
         while (top ) {  
             if (flag ) {              
                 if (stack [ --top ] == NULL ) { //在非NULL結點前仍有NULL結點  
                     return FALSE ;  
                 }  
             }  
             else {  
                 if (stack [ --top ] ! = NULL ) { //遇到第一個非NULL結點  
                    flag = 1 ;  
                 }  
             }  
         }  
     } //if      
     return TRUE ;  
}

6.65④ 已知一棵二叉樹的前序序列和中序序列分別
存於兩個一維數組中,試編寫算法建立該二叉樹的二
叉鏈表。
要求實現以下函數:
void BuildBiTree(BiTree &bt, int ps, char *pre,
int is, char *ino, int n);
/* 當前要建立的子樹bt的元素總數為n,*/
/* 元素在前序序列pre的起始位置為ps,*/
/* 元素在中序序列ino的起始位置為is */
二叉鏈表類型定義:
typedef char TElemType;
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

void BuildBiTree (BiTree  &bt,  int ps,  char  *pre,   
                              int is,  char  *ino,  int n )  
/* 當前要建立的子樹bt的元素總數為n,*/  
/* 元素在前序序列pre的起始位置為ps,*/  
/* 元素在中序序列ino的起始位置為is  */  
{  
    //估計此題比較繁瑣,待更新  
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM