Anyview第六章答案

DC06PE01

#include "allinclude.h"

int commonAncestor_0601(SqBiTree T, int i, int j)
/* 求出完全二叉树T中编号i和j的两个结点的
	 最近公共祖先结点的编号
	 i和j的范围不合理,则返回0
*/
{
	if (i < 1 || i > T.lastIndex || j < 1 || j > T.lastIndex)
		return 0;            // i和j的范围不合理
	while (i / 2 != j / 2) //直到相等(最后停止为i/2==1,即根结点
		if (i > j)
			i = i / 2;
		else
			j = j / 2;
	return i / 2;
}



DC06PE02

#include "allinclude.h"

Status is_Desendant0601(SqBiTree T, int u, int v) {
    if (u<1 || u>T.lastIndex || v<1 || v>T.lastIndex || v <= u)
        return 0; // u和v的范围不合理
    while (v > u) { // 根据性质5找v的祖先
        v = v / 2;
        if (v == u) 
            return TRUE; // v是u的子孙
    }
    return FALSE; // v不是u的子孙
}


DC06PE06

/**********
【题目】若两棵二叉树T1和T2皆为空,或者皆不空
且T1的左、右子树和T2的左、右子树分别相似,则
称二叉树T1和T2相似。试编写算法,判别给定两棵
二叉树是否相似。
二叉链表类型定义:
typedef struct BiTNode {
  TElemType  data;
  struct BiTNode  *lchild, *rchild;
} BiTNode, *BiTree;
**********/
#include "allinclude.h"
Status Similar_0606(BiTree T1, BiTree T2)
/* 判断两棵二叉树是否相似的递归算法 */
{
  if (NULL==T1 && NULL==T2) return TRUE;
  else if (T1!=NULL && T2!=NULL && 
           Similar_0606(T1->lchild, T2->lchild) &&
           Similar_0606(T1->rchild, T2->rchild))
    return TRUE;
  else return FALSE;
}



DC05PE33

/**********
【题目】试编写递归算法,输出广义表中所有原子项及其所在层次。
广义表类型GList的定义:
typedef enum {ATOM,LIST} ElemTag;
typedef struct GLNode{
     ElemTag tag;
     union {
       char atom;
       struct { 
         GLNode *hp, *tp;
       } ptr;
     }un;
} *GList;
**********/
#include "allinclude.h"
void OutAtom0533(GList A, int layer, void(*Out2)(char, int))
/* 递归地用函数Out2输出广义表的原子及其所在层次,layer表示当前层次 */
{
  if (!A) return;
  if (A->tag==ATOM) Out2(A->un.atom, layer);
  else {
    OutAtom0533(A->un.ptr.hp, layer+1, Out2);
    OutAtom0533(A->un.ptr.tp, layer, Out2); //注意尾表与原表是同一层次
  }
}




DC06PE11

/**********
【题目】编写递归算法,求对二叉树T先序遍历时
第k个访问的结点的值。
二叉链表类型定义:
typedef struct BiTNode {
  TElemType data;
  struct BiTNode  *lchild, *rchild;
} BiTNode, *BiTree;
**********/
#include "allinclude.h"
TElemType _Pre0611(BiTree T, int k, int &i);

TElemType PreOrderK_0611(BiTree T, int k)
/* 求对二叉树T先序遍历时第k个访问的结点的值。*/
/* 若失败,则返回'#'                         */
{ 
  int i=0;
  return _Pre0611(T,k,i);
}

TElemType _Pre0611(BiTree T, int k, int &i) {
  TElemType x;
  if (T==NULL) return '#';
  i++;
  if (i==k) return T->data;
  if ((x = _Pre0611(T->lchild,k,i))!='#') return x;
  return _Pre0611(T->rchild,k,i);
}



DC06PE23

/**********
【题目】试利用栈及其基本操作写出二叉树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); 
**********/
#include "allinclude.h"
void PostOrder_0623(BiTree T, Status (*visit)(TElemType))
/* 使用栈,非递归后序遍历二叉树T,     */
/* 对每个结点的元素域data调用函数visit */
{
  Status right;
  Stack S;
  InitStack(S);
  SElemType w;
  w.ptr=T;
  w.tag=0;
  BiTree p;
  do {
    while (w.ptr!=NULL) { 
      Push(S,w);
      w.ptr=w.ptr->lchild; 
    }
    right=TRUE;
    while (!StackEmpty(S) && right) {
      Pop(S,w);
      if (w.tag==1) {
        visit(w.ptr->data);
      } else {
        w.tag=1; 
        Push(S,w);  
        w.ptr=w.ptr->rchild;  
        w.tag=0;
        right=FALSE;
      }
    }
  } while (!StackEmpty(S));
}



DC06PE21

/**********
【题目】试利用栈及其基本操作写出二叉树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); 
**********/
#include "allinclude.h"
void PreOrder_0621(BiTree T, Status (*visit)(TElemType))
/* 使用栈,非递归先序遍历二叉树T,     */
/* 对每个结点的元素域data调用函数visit */
{
  BiTree p=T;
  Stack s;
  InitStack(s);  
  Push(s,NULL);
  while (p!=NULL) {
    visit(p->data);
    if (p->rchild!=NULL) Push(s, p->rchild);
    if (p->lchild!=NULL) p=p->lchild;
    else Pop(s,p);
  }
}



DC06PE12

/**********
【题目】编写递归算法,计算二叉树T中叶子结点的数目。
二叉链表类型定义:
typedef struct BiTNode {
  TElemType  data;
  struct BiTNode  *lchild, *rchild;
} BiTNode, *BiTree;
**********/
#include "allinclude.h"
int Leaves_0612(BiTree T)
/* 计算二叉树T中叶子结点的数目 */
{
  if (NULL==T) return 0;
  if (NULL==T->lchild && NULL==T->rchild) return 1;
  return Leaves_0612(T->lchild) + Leaves_0612(T->rchild);
}



DC06PE30

#include "allinclude.h"

Status Similar0636(BiTree t1, BiTree t2)
/* 判断两棵二叉树是否相似的递归算法 */
{
  if (!t1 && !t2) 
      return TRUE;
  else if (t1 && t2 && 
           Similar0636(t1->lchild,t2->lchild) &&
           Similar0636(t1->rchild,t2->rchild))
    return TRUE;
  else 
      return FALSE;
}




DC06PE27

/**********
【题目】二叉树采用三叉链表的存储结构,试编写
不借助栈的非递归中序遍历算法。
三叉链表类型定义:
typedef struct TriTNode {
  TElemType data;
  struct TriTNode  *parent, *lchild, *rchild;
} TriTNode, *TriTree;
**********/
#include "allinclude.h"
void InOrder_0627(TriTree PT, Status (*visit)(TElemType))
/* 不使用栈,非递归中序遍历二叉树PT,  */
/* 对每个结点的元素域data调用函数visit */
{
  TriTree p=PT;
  if (p) { // PT非空
    while (p->lchild) p=p->lchild; //向左走到尽头
    while (p) {
      visit(p->data);
      if (p->rchild) { //寻找中序后继:当有右子树时
        p=p->rchild;
        while (p->lchild) p=p->lchild; // 后继就是在右子树中向左走到尽头
      } else if (p->parent) {
        if (p->parent->lchild==p) { // 当*p是双亲的左孩子时后继就是双亲
          p=p->parent; 
        } else { // 当*p是双亲的右孩子时则后继是向上返回直到遇到*p是在其左子树中的祖先
          p=p->parent;
          if (p) {
            while (p->parent && p->parent->rchild==p) p=p->parent;
            p=p->parent;
          }  
        } 
      } else {
        p=N
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值