知识大全 数据结构第六章(树)习题答案(上)

Posted 结点

篇首语:案头见蠹鱼,犹胜凡俦侣。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 数据结构第六章(树)习题答案(上)相关的知识,希望对你有一定的参考价值。

  二 算法设计题

   二叉树的遍历算法可写为通用形式 例如通用的中序遍历为

  void Inorder(BinTree T void(* visit)(DataType x))

  if (T)

  Inorder(T >lchild Visit);//遍历左子树

  Visit(T >data);//通过函数指针调用它所指的函数来访问结点

  Inorder(T >rchild Visit);//遍历右子树

  

  

  其中Visit是一个函数指针 它指向形如void f(DataType x)的函数 因此我们可以将访问结点的操作写在函数f中通过调用语句Inorder(root f)将f的地址传递给Visit 来执行遍历操作 请写一个打印结点数据的函数 通过调用上述算法来完成书中 节的中序遍历

   解 这个函数如下

  void PrintNode(BinTree T)

  

  printf( %c T >data);

  

  为了验证这个函数是否正确 要先建立一棵二叉树 然后调用这个中序遍历算法 //定义二叉树链式存储结构

  typedef char DataType;//定义DataType类型

  typedef struct node

  DataType data;

  struct node *lchild *rchild;//左右孩子子树

  BinTNode; //结点类型 typedef BinTNode *BinTree ;//二叉树类型 #include

  #include

  void CreatBinTree(BinTree *T)//输入序列是先序序列

   //构造二叉链表 T是指向根的指针 故修改了*T就修改了实参

  char ch;

  if ((ch=getchar())== )

  *T=NULL;

  else //读入非空格

  *T=(BinTNode *)malloc(sizeof(BinTNode));//生成结点

  (*T) >data=ch;

  CreatBinTree(&(*T) >lchild); //构造左子树

  CreatBinTree(&(*T) >rchild); //构造右子树

  

  

  //

  void PrintNode(DataType x)

   //题目要求的打印函数

  printf( %c x);

  

  //

  void Inorder(BinTree T void(* Visit)(DataType x))

  

  if(T)

  

  Inorder(T >lchild Visit);//遍历左子树

  Visit(T >data); //通过函数指针调用它所指的函数访问结点

  Inorder(T >rchild Visit);//遍历右子树

  

  

  void main()

   //现在开始测试啦 BinTree root; //定义一个根结点

  CreatBinTree(&root); //建立二叉链表

  printf( \\n );

  Inorder(root PrintNode);//调用函数 注意传递的是函数名(它就是地址)

  printf( \\n );

  

  //运行时请输入 ab c (注意b后和c后面各两个空格)再回车 可生成一个以a为根的两片叶子的二叉树 看看打印的结果对不对?

   以二叉链表为存储结构 分别写出求二叉树结点总数及叶子总数的算法

  解 利用中序遍历 我们很容易地就能找到这个算法每访问一次非空结点就给变量nodes加上 ; 每访问到一个其左右子树皆空的结点就给变量leaves加上 最后就得到结果了

  完整程序如下所示 //定义二叉树链式存储结构等内容 为方便起见我们将这一段内容存为bintree h文件 以后只在程序中加入这个头文件就是了 // bintree h 文件开始 typedef char DataType;//定义DataType类型

  typedef struct node

  DataType data;

  struct node *lchild *rchild;//左右孩子子树

  BinTNode; //结点类型 typedef BinTNode *BinTree ;//二叉树类型 #include

  #include

  void CreatBinTree(BinTree *T)

   //构造二叉链表 注意:输入序列是先序序列

  char ch;

  if ((ch=getchar())== )

  *T=NULL;

  else //读入非空格

  *T=(BinTNode *)malloc(sizeof(BinTNode));//生成结点

  (*T) >data=ch;

  CreatBinTree(&(*T) >lchild); //构造左子树

  CreatBinTree(&(*T) >rchild); //构造右子树

  

  // 文件结束 // 以下两个函数为题目要求算法 int Node(BinTree T)

   //算结点数

  int static nodes= ;//静态变量保留每次递归调用后的值

  if(T)

   //使用中序遍历

  Node(T >lchild); //遍历左子树

  nodes++; //结点数加

  Node(T >rchild); //遍历右子树

  

  return nodes;

   int Leaf(BinTree T)

   //算叶子数

  int static leaves= ;//静态变量保证其值不会随递归调用而消失

  if(T)

   //使用中序遍历

  Leaf(T >lchild); //遍历左子树

  if(!(T >lchild||T >rchild))//左右孩子均为空

  leaves++; //叶子数加

  Leaf(T >rchild); //遍历右子树

  

  return leaves;

  //算法结束 #include

  void main()

   //测试程序

  BinTree root;

  CreatBinTree(&root);

  int nodes=Node(root);

  int leaves=Leaf(root);

  printf( \\nnodes=%d leaves=%d nodes leaves);

  

   以二叉链表为存储结构 分别写出求二叉树高度及宽度的算法 所谓宽度是指二叉树的各层上 具有结点数最多的那一层上的结点总数

  解 要想求出二叉树的高度 可以采用前序遍历 设一个个记录高度的变量h 在访问结点时查询该结点是否有孩子 有则高度加 其中根结点比特殊 自身算一层 要求二叉树的宽度的话 则可根据树的高度设置一个数组 在访问结点时计算该结点下一层的孩子数并存入相应数组元素中 遍历左子树后向上返回一层计算右子树的宽度 并取出最大的一个数组元素作为树的宽度

  #include

  #include bintree h

  #define M //假设二叉树最多的层数

  int Height(BinTree T)//求树的深度

   //求深度算法由阮允准更正 在此深表感谢

  int lhigh rhigh high= ;

  if(T!=NULL)

  

  lhigh=Height(T >lchild);//左子树高度

  rhigh=Height(T >rchild);//右子树高度

  high=(lhigh>rhigh?lhigh:rhigh)+ ;//树的高度等于左子树 右子树之间的大者加上根结点

  

  return high;

   int Width(BinTree T)

  

  int static n[M];//向量存放各层结点数

  int static i= ;

  int static max= ;//最大宽度

  if(T)

  

  if(i== ) //若是访问根结点

  

  n[i]++; //第 层加

  i++; //到第 层

  if(T >lchild)//若有左孩子则该层加

  n[i]++;

  if(T >rchild)//若有右孩子则该层加

  n[i]++;

  

  else

   //访问子树结点

  i++; //下一层结点数

  if(T >lchild)

  n[i]++;

  if(T >rchild)

  n[i]++;

  

  if(max

  Width(T->lchild);//遍历左子树

  i--; //往上退一层

  Width(T->rchild);//遍历右子树

  

  return max;

  //算法结束 void main()

   //测试程序

  BinTree root;

  CreatBinTree (&root);

  printf("\\nHeight of BinTree:%d",Height(root));

  printf("\\nWidth of BinTree:%d",Width(root));

  

  6.25 以二叉链表为存储结构, 写一算法交换各结点的左右子树。Tw.WiNgWiT.

  要交换各结点的左右子树,最方便的办法是用后序遍历算法,每访问一个结点时把两棵子树的指针进行交换,最后一次访问是交换根结点的子树。

  #include

  #include "bintree.h"

  void ChangeBinTree(BinTree *T)

   //交换子树

  if(*T)

   //这里以指针为参数使得交换在实参的结点上进行

  //后序遍历

  BinTree temp;

  ChangeBinTree(&(*T)->lchild);

  ChangeBinTree(&(*T)->rchild);

  temp=(*T)->lchild;

  (*T)->lchild=(*T)->rchild;

  (*T)->rchild=temp;

  

  

  void PrintNode(BinTree T)

   //以前序序列打印结点数据

  if(T)

  

  printf("%c",T->data);

  PrintNode(T->lchild);

相关参考