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

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);

相关参考

知识大全 数据结构考研分类复习真题 第六章 答案 (四)[1]

  第六章树和二叉树答案(四)  四.应用题  .树的孩子兄弟链表表示法和二叉树二叉链表表示法本质是一样的只是解释不同也就是说树(树是森林的特例即森林中只有一棵树的特殊情况)可用二叉树唯一表示并可使用

知识大全 数据结构考研分类复习真题 第六章 答案 (五)[11]

  .[题目分析]由孩子兄弟链表表示的树求高度的递归模型是若树为空高度为零若第一子女为空高度为和兄弟子树的高度的大者否则高度为第一子女树高度加和兄弟子树高度的大者其非递归算法使用队列逐层遍历树取得树的

知识大全 数据结构考研分类复习真题 第六章 答案 (五)[2]

  [题目分析]本题是将符号算术表达式用二叉树表示的逆问题即将二叉树表示的表达式还原成原表达式二叉树的中序遍历序列与原算术表达式基本相同差别仅在于二叉树表示中消除了括号将中序序列加上括号就恢复原貌当根

知识大全 数据结构考研分类复习真题 第六章 答案 (五)[24]

  [题目分析]二叉树结点p所对应子树的第一个后序遍历结点q的求法如下若p有左子树则q是p的左子树上最左下的叶子结点若p无左子树仅有右子树则q是p的右子树上最左下的叶子结点  BiTreePostFi

知识大全 数据结构考研分类复习真题 第六章 答案 (五)[7]

  [题目分析]二叉树采用顺序存储结构(一维数组)是按完全二叉树的形状存储的不是完全二叉树的二叉树顺序存储时要加虚结点数组中的第一个元素是根结点本题中采用队列结构  typedefstruct  Bi

知识大全 数据结构考研分类复习真题 第六章 答案 (五)[13]

  [题目分析]二叉树顺序存储是按完全二叉树的格式存储利用完全二叉树双亲结点与子女结点编号间的关系求下标为i和j的两结点的双亲双亲的双亲等等直至找到最近的公共祖先  voidAncestor(Elem

知识大全 数据结构考研分类复习真题 第六章 答案 (四)[28]

  树的后根遍历(对应二叉树的中序遍历)全线索链表    虽然哈夫曼树的带权路径长度是唯一的但形态不唯一本题中各字母编码如下c: c: c: c: c:&nbs

知识大全 数据结构考研分类复习真题 第六章 答案 (五)[28]

  [题目分析]此树看作度为的有序树先将根结点入队列当队列不空重复以下动作结点出队若结点有两个子女先将第二(右)子女入队列并转向第一子女若结点有一个子女则入队列如此下去直到碰到叶子结点或只有一个子女的

知识大全 数据结构考研分类复习真题 第六章 答案 (五)[1]

  第章树和二叉树答案(五)  五.算法设计题  .[题目分析]以二叉树表示算术表达式根结点用于存储运算符若能先分别求出左子树和右子树表示的子表达式的值最后就可以根据根结点的运算符的要求计算出表达式的

知识大全 数据结构考研分类复习真题 第六章 答案 (五)[35]

  [题目分析]按题目要求每个结点的编号大于其左右孩子的编号结点左孩子的编号小于右孩子的编号由此看出从小到大按左右根顺序这正是后序遍序的顺序故对二叉树进行后序遍历在遍历中对结点进行编号现将二叉树结点结