厂工数据结构Anyview(C语言版)第六章答案

第六章

一、判别两棵二叉树是否相似

【题目】若两棵二叉树T1和T2皆为空,或者皆不空且T1的左、右子树和T2的左、右子树分别相似,则称二叉树T1和T2相似。试编写算法,判别给定的两棵二叉树是否相似。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

要求实现下列函数:

// 如果T1和T2相似,则返回TRUE;否则返回FALSE
Status Similar(BiTree T1, BiTree T2);

#include "allinclude.h"  //DO NOT edit this line
Status Similar(BiTree T1, BiTree T2){
    // Add your code here
    
    //递归
    if(!T1&&!T2) return TRUE;
    
    if(T1&&T2){
      
      if(Similar(T1->lchild,T2->lchild)&&Similar(T1->rchild,T2->rchild)) return TRUE;
    }
    
    return FALSE;
} 

二、编写递归算法,求对二叉树T先序遍历时第k个访问的结点的值

【题目】编写递归算法,求对二叉树T先序遍历时第k个访问的结点的值。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

要求实现下列函数:
TElemType PreOrderK(BiTree T, int k);
/* 求对二叉树T先序遍历时第k个访问的结点的值。/
/
若失败,则返回’#’ */

#include "allinclude.h"  //DO NOT edit this line
TElemType PreOrder(BiTree T, int &rek){//原题接口中参数k没有取地址符号&,递归无法实现,需要再写一个函数
    
    TElemType re = '#';  
    
    if(!T||rek < 1) return '#';
    
    if(rek == 1) return T->data;    
    
    rek--;
    
    if(T->lchild)
        re = PreOrder(T->lchild,rek);//不能写rek-1    
    if(T->rchild && re == '#')
        re = PreOrder(T->rchild,rek);
    return re;  
}

TElemType PreOrderK(BiTree T, int k){ 
    
    return PreOrder(T,k);
} 

三、编写递归算法,计算二叉树T中叶子结点的数目

【题目】编写递归算法,计算二叉树T中叶子结点的数目。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

要求实现下列函数:
int Leaves(BiTree T);
/* 计算二叉树T中叶子结点的数目 */

#include "allinclude.h"  //DO NOT edit this line
int Leaves(BiTree T){ 
    // Add your code here
    
    if(!T) return 0;
    
    //只有根,就是一片树叶
    if(!T->lchild&&!T->rchild) return 1;
      
    return Leaves(T->lchild)+Leaves(T->rchild);
} 

四、试利用栈及其基本操作写出二叉树T的非递归的先序遍历算法

【题目】试利用栈及其基本操作写出二叉树T的非递归的先序遍历算法。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct 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 T, void (visit)(TElemType));
/
使用栈,非递归先序遍历二叉树T, /
/
对每个结点的元素域data调用函数visit */

#include "allinclude.h"  //DO NOT edit this line
void PreOrder(BiTree T, Status (*visit)(TElemType)){ 
    // Add your code here
    
    //创建栈S
    Stack S;
    InitStack(S);
    
    BiTree p;
    
    p = T;
    
    while(p){
      
      visit(p->data);
      
      if(p->rchild) Push(S,p->rchild);
      
      if(p->lchild) p = p->lchild;
      else if(!StackEmpty(S)) Pop(S,p);
      else p = NULL;
    }
} 

五、试利用栈及其基本操作写出二叉树T的非递归的后序遍历算法

【题目】试利用栈及其基本操作写出二叉树T的非递归的后序遍历算法(提示:为分辨后序遍历时两次进栈的不同返回点,需在指针进栈时同时将一个标志进栈)。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;

可用栈类型Stack的相关定义:
typedef struct {
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 T, void (visit)(TElemType));
/
使用栈,非递归后序遍历二叉树T, /
/
对每个结点的元素域data调用函数visit */

#include "allinclude.h"  //DO NOT edit this line
void PostOrder(BiTree T, Status (*visit)(TElemType)){ 
    // Add your code here
    
    if(!T) return ;
    
    //建一个栈
    Stack s;
    InitStack(s);
    
    //建立栈元素
   SElemType n;
    n.ptr = T;
    n.tag =0;//tag为012,分别代表VLR
    
    //先把根结点入栈
    Push(s,n);
    
    while(!StackEmpty(s)){
      
      //先出栈
      Pop(s,n);
      
      if(n.tag == 0){
        
        n.tag = 1;
        Push(s,n);
        
        if(n.ptr->lchild){
          
          n.ptr = n.ptr->lchild;
          n.tag = 0;
          Push(s,n);
        }
      }else if(n.tag == 1){
        
        n.tag = 2;
        Push(s,n);
        
        if(n.ptr->rchild){
          
          n.ptr = n.ptr->rchild;
          n.tag = 0;
          Push(s,n);
        }
      }else visit(n.ptr->data);
    }
} 

六、二叉树采用三叉链表的存储结构,试编写不借助栈的非递归中序遍历算法

【题目】二叉树采用三叉链表的存储结构,试编写不借助栈的非递归中序遍历算法。

三叉链表类型定义:
typedef struct TriTNode {
TElemType data;
struct TriTNode *parent, *lchild, *rchild;
} TriTNode, *TriTree;

要求实现以下函数:
void InOrder(TriTree PT, void (visit)(TElemType));
/
不使用栈,非递归中序遍历二叉树PT, /
/
对每个结点的元素域data调用函数visit */

#include "allinclude.h"  //DO NOT edit this line
void InOrder(TriTree PT, Status (*visit)(TElemType)){ 
    // Add your code here
    
    if(!PT) return ;
    
    TriTree p;
    
    p = PT;
    
    //找到最左子树
    while(p->lchild) p = p->lchild;
    
    while(p){
      
      visit(p->data);
      
      if(!p->parent&&!p->rchild) break;
      
      if(p->rchild){
        
        p = p->rchild;
        
        //遍历右子树的左子树
        while(p->lchild) p = p->lchild;
      }
      else if(p->parent->lchild == p) p = p->parent;
      else{
        
        p = p->parent;
        
        while(p->parent&&p->parent->rchild == p){
          
          p = p->parent;
        }
        p = p->parent;
      }
    }
} 

七、编写不用栈辅助的二叉树非递归后序遍历算法

【题目】假设在三叉链表的结点中增设一个标志域(mark取值0,1或2)以区分在遍历过程中到达该结点时应继续向左或向右或访问该结点。试以此存储结构编写不用栈辅助的二叉树非递归后序遍历算法。
带标志域的三叉链表类型定义:
typedef struct TriTNode {
TElemType data;
struct TriTNode *lchild, *rchild, *parent;
int mark; // 标志域
} TriTNode, *TriTree;

要求实现以下函数:
void PostOrder(TriTree T, Status (visit)(TElemType));
/
不使用栈,非递归后序遍历二叉树T, /
/
对每个结点的元素域data调用函数visit */

#include "allinclude.h"  //DO NOT edit this line
void PostOrder(TriTree T, Status (*visit)(TElemType)){ 
    // Add your code here
    TriTree p = T;
    
    while(p){
      
      //如果当前访问结点标志为0,则依次把左子树的标志改为1,直到最左子树
      while(p->mark == 0){
        
        p->mark = 1;
        if(p->lchild) p = p->lchild;
      }
      
      //如果当前结点标志为1,则表示其左子树已被访问,先将其标志依次改为2,等待右子树访问完后再访问自己
      while(p->mark == 1){
        
        p->mark = 2;
        if(p->rchild) p = p->rchild;
      }
      
      //如果当前结点为2,则进行访问,并返回双亲结点
      if(p->mark == 2){
        
        visit(p->data);
        
        p = p->parent;
      }
    }
} 

八、编写递归算法,将二叉树中所有结点的左、右子树相互交换

【题目】编写递归算法,将二叉树中所有结点的左、右子树相互交换。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

要求实现下列函数:
void ExchangeSubTree(BiTree &T);
/* 将二叉树中所有结点的左、右子树相互交换 */

#include "allinclude.h"  //DO NOT edit this line
void ExchangeSubTree(BiTree &T){ 
    // Add your code here
    
    if(!T) return;
    
    BiTree p;
    
    //如果左右孩子都是空就不用交换了
    if(T->lchild||T->rchild){
      
      p = T->lchild;
      T->lchild = T->rchild;
      T->rchild = p;
    }
    
   ExchangeSubTree(T->lchild);
   ExchangeSubTree(T->rchild);
} 

九、编写递归算法:求二叉树中以元素值为x的结点为根的子树的深度

【题目】编写递归算法:求二叉树中以元素值为x的结点为根的子树的深度。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

要求实现下列函数:
int Depthx(BiTree T, TElemType x);
/* 求二叉树中以值为x的结点为根的子树深度 */

#include "allinclude.h"  //DO NOT edit this line
int Depthx(BiTree T, TElemType x){ 
    // Add your code here
    
    if(!T) return 0;
    
    if(T){
      
      int lt,rt;
      
      if(T->data == x){
        
        //要加上两个if条件,不然T->lchild为空时,T->lchild->data不存在,会报错
        if(!T->lchild) lt = 0;
        else lt = Depthx(T->lchild,T->lchild->data);
        
        if(!T->rchild) rt = 0;
        else rt = Depthx(T->rchild,T->rchild->data);
        
        return 1+(lt>rt?lt:rt);
      }else{
        
        lt = Depthx(T->lchild,x);
        rt = Depthx(T->rchild,x);
        
        return lt>rt?lt:rt;
      }
    }
}

十、 编写递归算法:对于二叉树中每一个元素值为x的结点,删去以它为根的子树,并释放相应的空间

【题目】编写递归算法:对于二叉树中每一个元素值为x的结点,删去以它为根的子树,并释放相应的空间。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

要求实现下列函数:
void ReleaseX(BiTree &T, char x);
/* 对于二叉树中每一个元素值为x的结点, /
/
删去以它为根的子树,并释放相应的空间 */

#include "allinclude.h"  //DO NOT edit this line
void ReleaseX(BiTree &T, char x){ 
    // Add your code here
    
    if(!T) return;
    
    if(T->data == x){
      
      if(T->lchild)
     
        ReleaseX(T->lchild,T->lchild->data);
        if(T->rchild)
        ReleaseX(T->rchild,T->rchild->data);
      
      //free(T);
      T = NULL;
     }else{
        
      ReleaseX(T->lchild,x);
      ReleaseX(T->rchild,x);
     }
}

十一、编写复制一棵二叉树的递归算法

【题目】编写复制一棵二叉树的递归算法。

二叉链表类型定义:
typedef char TElemType; // 设二叉树的元素为char类型
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

要求实现下列函数:
void CopyBiTree(BiTree T, BiTree &TT);
/* 递归复制二叉树T得到TT */

#include "allinclude.h"  //DO NOT edit this line
void CopyBiTree(BiTree T, BiTree &TT){ 
    // Add your code here
    
    if(!T) TT = NULL;
    else{
      
      //每次运行到这都要开拓新的空间
      TT = (BiTree)malloc(sizeof(BiTNode));
      
      TT->data = T->data;
      
      CopyBiTree(T->lchild,TT->lchild);
      CopyBiTree(T->rchild,TT->rchild);
    }
} 

十二、编写算法判别给定二叉树是否为完全二叉树

【题目】编写算法判别给定二叉树是否为完全二叉树。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct 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 T);
/* 判别二叉树T是否为完全二叉树 */

#include "allinclude.h"  //DO NOT edit this line
Status CompleteBiTree(BiTree T){ 
    // Add your code here
    
    if(!T) return TRUE;
    
    int flag = 0;
    Queue Q;
    BiTree p = T;
    
    //构建一个空队列
    InitQueue(Q);
   
    //根结点入队
    EnQueue(Q,p);
    
    while(DeQueue(Q,p)){
      
      if(!p) flag = 1;
      else if(flag) return FALSE;
      else{
        
        EnQueue(Q,p->lchild);
        EnQueue(Q,p->rchild);
      }
    }
    
    return TRUE;
} 

十三、试编写一个二叉排序树的判定算法

【题目】试编写一个二叉排序树的判定算法。

二叉排序树的类型BSTree定义如下:
typedef struct {
KeyType key;
… … // 其他数据域
} TElemType;

typedef struct BiTNode {
TElemType data;
struct BSTNode *lchild, *rchild;
}BSTNode, *BSTree;

实现下列函数:
Status IsBSTree(BSTree T);
/* 判别二叉树T是否为二叉排序树。/
/
若是,则返回TRUE,否则FALSE */

#include "allinclude.h"  //DO NOT edit this line
Status IsBSTree(BSTree T){ 
    // Add your code here
    
    if(!T||(!T->lchild&&!T->rchild)) return TRUE;
    
    if(T->lchild)
    
    if(T->lchild->data.key >= T->data.key) return FALSE;
    
    if(T->rchild)
    if(T->rchild->data.key <= T->data.key) return FALSE;
    
    if(IsBSTree(T->lchild)) return IsBSTree(T->rchild);
    
    return FALSE; 
} 

十四、 编写递归算法,从大到小输出给定二叉排序树中所有关键字不小于x的数据元素

【题目】编写递归算法,从大到小输出给定二叉排序树中所有关键字不小于x的数据元素。

二叉排序树的类型BSTree定义如下:
typedef struct {
KeyType key;
… … // 其他数据域
} TElemType;

typedef struct BSTNode {
TElemType data;
struct BSTNode *lchild,*rchild;
}BSTNode, *BSTree;

实现下列函数:
void OrderOut(BSTree T, KeyType k, void(visit)(TElemType));
/
调用visit(T->data)输出 */

#include "allinclude.h"  //DO NOT edit this line
void OrderOut(BSTree T, KeyType k, void(*visit)(TElemType)){ 
    // Add your code here
    
    if(!T) return;
    
    //大的在右边
    OrderOut(T->rchild,k,visit);
    
    if(T->data.key >= k){
      
      visit(T->data);
      
      OrderOut(T->lchild,k,visit);
    }
} 

十五、试写一非递归算法,在二叉查找树T中插入元素e

【题目】试写一非递归算法,在二叉查找树T中插入元素e。

二叉查找树的类型BSTree定义如下:
typedef struct {
KeyType key;
… … // 其他数据域
} TElemType;

typedef struct BSTNode {
TElemType data;
struct BSTNode *lchild,*rchild;
} BSTNode, *BSTree;

实现下列函数:
Status InsertBST_I(BSTree &T, TElemType k);
/* 在二叉查找树T中插入元素e的非递归算法 */

#include "allinclude.h"  //DO NOT edit this line
Status InsertBST_I(BSTree &T, TElemType k){ 
    // Add your code here
    
    BSTree s,p = T;
    
    s = (BSTree)malloc(sizeof(BSTNode));
    if(!s) return OVERFLOW;
    s->data = k;
    s->lchild = NULL;
    s->rchild = NULL;
    
    while(T){
      
      if(p->data.key == k.key) return OVERFLOW;
      
      if(p->data.key > k.key){
        
        if(p->lchild) p = p->lchild;
        else p->lchild = s;
      }else{
        
        if(p->rchild) p = p->rchild;
        else p->rchild = s;
      }
    }
} 

十六、试编写算法,求二叉树T中结点a和b的最近共同祖先

【题目】试编写算法,求二叉树T中结点a和b的最近共同祖先。

二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;

可用栈类型Stack的相关定义:
typedef struct {
BiTNode *ptr; // 二叉树结点的指针类型
int tag; // 0…1
} SElemType; // 栈的元素类型

Status InitStack(Stack &S);
Status StackEmpty(Stack S);
int StackLength(SqStack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);

要求实现下列函数:
BiTree CommAncestor(BiTree T, TElemType a, TElemType b);
/* 求二叉树T中结点a和b的最近共同祖先 */

#include "allinclude.h"  //DO NOT edit this line
Status Get(BiTree t, TElemType v, Stack &s){//构建一个寻找结点位置的函数
  
  if(!t) return ERROR;
  
  SElemType e;
  e.ptr = t;
  
  if(t->data == v){
    
    Push(s,e);
    return OK;
  }
  
  if(OK == Get(t->lchild,v,s)){
    
    Push(s,e);
    return OK;
  }
  
  if(OK == Get(t->rchild,v,s)){
    
    Push(s,e);
    return OK;
  }
  
  return ERROR;
}

BiTree CommAncestor(BiTree T, TElemType a, TElemType b){ 
    // Add your code here
    if(!T) return NULL;
    
    //构建两个栈
    Stack Sa,Sb;
    
    InitStack(Sa);
    InitStack(Sb);
    
    //如果找不到a,b两个结点
    if(!Get(T,a,Sa)||!Get(T,b,Sb)) return NULL;
    
    SElemType e1,e2,E1,E2;
    
    //先把两个栈顶元素取出来
    Pop(Sa,E1);
    Pop(Sb,E2);
    
    while(!StackEmpty(Sa)&&!StackEmpty(Sb)){
      
      //先把刚取出来的元素记住
      e1 = E1;
      e2 = E2;
      
      //再分别取出下一个栈顶元素
      if(!Pop(Sa,E1)||!Pop(Sb,E2)||E1.ptr->data != E2.ptr->data||E1.ptr->data == a||E2.ptr->data == b)
        return e1.ptr;
    }
    
    return NULL;
} 

十七、求树中第k小的结点的位置

【题目】在二叉排序树的每个结点中增设一个lsize域,其值为该结点的左子树中的结点数加1。试编写时间复杂度为O(logn)的算法,求树中第k小的结点的位置。

二叉排序树的类型BSTree定义如下:
typedef char KeyType;

typedef struct BSTNode {
KeyType key;
struct BSTNode *lchild,*rchild;
int lsize; // 新增域,值为左子树的结点数+1
} BSTNode, *BSTree;

实现下列函数:
BSTNode Ranking(BSTree T, int k);
/
在含lsize域的二叉排序树T中,/
/
求指向T中第k小的结点的指针 */

#include "allinclude.h"  //DO NOT edit this line
BSTNode *Ranking(BSTree T, int k){ 
    // Add your code here
    
    if(!T) return NULL;
    
    if(T->lsize == k) return T;
    
    if(T->lsize > k) return Ranking(T->lchild,k);
    else return Ranking(T->rchild,k-T->lsize);
} 

十八、 假设二叉排序树T的每个结点的平衡因子域bf当前均为0。试编写算法,求二叉排序树T的深度,并为每个结点的bf域赋予正确的平衡因子值

【题目】假设二叉排序树T的每个结点的平衡因子域bf当前均为0。试编写算法,求二叉排序树T的深度,并为每个结点的bf域赋予正确的平衡因子值。

平衡二叉排序树的类型BBSTree定义如下:
typedef char KeyType;
typedef struct BBSTNode {
KeyType key;
int bf; // 平衡因子
struct BBSTNode *lchild,*rchild;
} BBSTNode, *BBSTree;

实现下列函数:
int Depth_BF(BBSTree T);
/* 求二叉排序树T的深度,并为每个结点 /
/
的bf域赋予正确的平衡因子值。 */

#include "allinclude.h"  //DO NOT edit this line
int Depth_BF(BBSTree T){ 
    // Add your code here
    
    int lf,rf;
    
    if(!T) return 0;
    else{
      
      lf = Depth_BF(T->lchild);
      rf = Depth_BF(T->rchild);
      
      T->bf = lf-rf;
    
      return 1+(lf>rf?lf:rf);
    }
} 

十九、编写平衡二叉排序树的右平衡处理算法

【题目】编写平衡二叉排序树的右平衡处理算法。

平衡二叉排序树的类型BBSTree定义如下:
typedef char KeyType;
typedef struct BBSTNode {
KeyType key;
int bf; // 平衡因子
struct BBSTNode *lchild,*rchild;
} BBSTNode, *BBSTree;

可调用下列旋转调整操作:
void L_Rotate(BBSTree &p); // 对最小失衡子树p做左旋调整
void R_Rotate(BBSTree &p); // 对最小失衡子树p做右旋调整

实现下列函数:
void RightBalance(BBSTree &T);
/* 实现对二叉树T的右平衡处理 */

#include "allinclude.h"  //DO NOT edit this line
void RightBalance(BBSTree &T){ 
    // Add your code here
    
    BBSTree lc,rd;
    
    rd = T->rchild;
    
    switch(rd->bf){
      
      case -1:
        rd->bf = T->bf = 0;
        L_Rotate(T);
        break;
      case 1:
        lc = rd->lchild;
        switch(rd->bf){
          
          case -1:T->bf = 1;rd->bf = 0;break;
          case 0:T->bf = rd->bf = 0;break;
          case 1:T->bf = 0;rd->bf = -1;break;
        }
        
        lc->bf = 0;
        R_Rotate(T->rchild);
        L_Rotate(T);
        break;
    }
}
  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值