anyview 数据结构习题集 第6章答案

时间:2024-03-05 11:40:51

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  */  
{  
   //估计此题比较繁琐,待更新  
}