第1关:先序遍历创建二叉链表存储的二叉树及遍历操作
编程要求
根据提示,在右侧编辑器补充代码。
-
InitBiTree(BiTree &T)
//构造空二叉树T -
CreateBiTree(BiTree &T)
//按先序遍历次序输入二叉树中结点的值(字符型或整型), 构造二叉链表存储的二叉树T -
PreOrderTraverse(BiTree T,void(*Visit)(TElemType))
//先序遍历二叉树T,对每个结点调用函数Visit一次且仅一次 -
InOrderTraverse(BiTree T,void(*Visit)(TElemType))
//中序遍历二叉树T,对每个结点调用函数Visit一次且仅一次 -
PostOrderTraverse(BiTree T,void(*Visit)(TElemType))
//后序遍历二叉树T,对每个结点调用函数Visit一次且仅一次 -
void DestoryBiTree(BiTree &T)
// 销毁二叉树 -
#define ClearBiTree DestroyBiTree
// 清空二叉树和销毁二叉树的操作一样
测试说明
平台会对你编写的代码进行测试:
测试输入: ABD##FE###CG#H##I##
预期输出: 先序遍历为:A,B,D,F,E,C,G,H,I,
中序遍历为:D,B,E,F,A,G,H,C,I,
后序遍历为:D,E,F,B,H,G,I,C,A,
#include <stdio.h>
#include <stdlib.h>
#include "bitree.h"
TElemType Nil='#';
void visit(TElemType s)
{
printf("%c,",s);
}
void input(TElemType &s)
{
scanf("%c",&s);
}
void CreateBiTree(BiTree &T)
{ //按先序次序输入二叉树中结点的值
// 构造二叉链表表示的二叉树T。变量Nil表示空(子)树。
/********** Begin **********/
TElemType ch;
scanf("%c",&ch);
if(ch=='#')
T=NULL;
else{
T=(BiTree)malloc(sizeof(BiTNode));
if(!T)
exit(OVERFLOW);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
/********** End **********/
}
int BiTreeEmpty(BiTree T)
{ // 初始条件:二叉树T存在。操作结果:若T为空二叉树,则返回TRUE,否则FALSE
/********** Begin **********/
if(T)
return FALSE;
else
return TRUE;
/********** End **********/
}
void ProOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ // 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。
// 先序遍历二叉树T的递归算法,对每个数据元素调用函数Visit
/********** Begin **********/
if(T){
Visit(T->data);
ProOrderTraverse(T->lchild,Visit);
ProOrderTraverse(T->rchild,Visit);
}
/********** End **********/
}
void InOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ // 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。
// 中序遍历二叉树T的递归算法,对每个数据元素调用函数Visit
/********** Begin **********/
if(T){
InOrderTraverse(T->lchild,Visit);
Visit(T->data);
InOrderTraverse(T->rchild,Visit);
}
/********** End **********/
}
void PostOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ // 初始条件:二叉树T存在,Visit是对结点操作的应用函数
// 操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次
/********** Begin **********/
if(T){
PostOrderTraverse(T->lchild,Visit);
PostOrderTraverse(T->rchild,Visit);
Visit(T->data);
}
/********** End **********/
}
void DestoryBiTree(BiTree &T)
{ // 初始条件:二叉树T存在。操作结果:销毁二叉树T
/********** Begin **********/
if(T){
DestoryBiTree(T->lchild);
DestoryBiTree(T->rchild);
free(T);
T=NULL;
}
/********** End **********/
}
第2关:计算二叉树的高度、总节点个数和叶子节点个数
编程要求
本关的编程任务是补全右侧代码中 Begin
至End
中间的代码,具体要求如下:
- int BiTreeDepth(BiTree T); //计算该二叉树的深度,返回深度值
- int NodeCount(BiTree T); //计算该二叉树的总的节点个数,返回节点个数
- int LeafNodeCount(BiTree T); //算该二叉树的叶子节点个数,返回叶子节点个数
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入: ABC##D##EF###
预期输出: 该树的高度为:3
节点的数目为: 6
叶子节点的数目为: 3
测试输入: ABCD###E#F##G##
预期输出: 该树的高度为:4
节点的数目为: 7
叶子节点的数目为: 3
#include <stdio.h>
#include <stdlib.h>
#include "bitree.h"
int BiTreeDepth(BiTree T);//计算该二叉树的深度,返回深度值
int NodeCount(BiTree T);//计算该二叉树的总的节点个数,返回节点个数
int LeafNodeCount(BiTree T);//算该二叉树的叶子节点个数,返回叶子节点个数
int main()
{
BiTree T;
CreateBiTree(T);
printf("该树的高度为:%d\n",BiTreeDepth(T));
printf("节点的数目为: %d\n",NodeCount(T));
printf("叶子节点的数目为: %d\n",LeafNodeCount(T));
DestoryBiTree(T);
return 0;
}
int BiTreeDepth(BiTree T)
{ // 初始条件:二叉树T存在。操作结果:返回T的深度
/********** Begin **********/
int i,j;
if(!T) return 0;
if(T->lchild)
i=BiTreeDepth(T->lchild);
else
i=0;
if(T->rchild)
j=BiTreeDepth(T->rchild);
else
j=0;
return i>j?i+1:j+1;
/********** End **********/
}
int NodeCount(BiTree T)
{
//初始条件:二叉树T存在。操作结果:返回T的结点数
/********** Begin **********/
if(!T)
return 0;
else
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
/********** End **********/
}
int LeafNodeCount(BiTree T)
{
//初始条件:二叉树T存在。操作结果:返回T的叶子结点数
/********** Begin **********/
if(!T)
return 0;
else
if(!T->lchild && !T->rchild)
return 1;
else
return LeafNodeCount(T->lchild)+LeafNodeCount(T->rchild);
/********** End **********/
}
第3关:层次遍历二叉树
编程要求
本关的编程任务是补全右侧代码中Begin
至End
中间的代码,具体要求如下:
void LevelOrderTraverse(BiTree T,void(*Visit)(TElemType));
//层次遍历二叉树
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:ABC##D##EF###
预期输出:层序遍历为:A,B,E,C,D,F,
测试输入:ABD##FE###CG#H##I##
预期输出:层序遍历为:A,B,C,D,F,G,I,E,H,
#include <stdio.h>
#include <stdlib.h>
#include "bitree.h"
#include "linkqueue.h"
void LevelOrderTraverse(BiTree T,void(*Visit)(TElemType));
int main()
{
BiTree T;
CreateBiTree(T);
printf("层序遍历为:");
LevelOrderTraverse(T,visit);
DestoryBiTree(T);
return 0;
}
void LevelOrderTraverse(BiTree T,void(*Visit)(TElemType))
{ // 初始条件:二叉树T存在,Visit是对结点操作的应用函数
// 操作结果:层序递归遍历T(利用队列),对每个结点调用函数Visit一次且仅一次
/********** Begin **********/
if(T) return;
BiTree p;
LinkQueue q;
InitQueue(q);
EnQueue(q,T);
while(!QueueEmpty(q))
{
DeQueue(q,p);
Visit(p->data);
if(p->lchild)
EnQueue(q,p->lchild);
if(p->rchild)
EnQueue(q,p->rchild);
}
DestroyQueue(q);
/********** End **********/
}
第4关:递归实现二叉树左右子树交换
编程要求
本关的编程任务是补全右侧代码中Begin
至End
中间的代码,具体要求如下:
- 在
exchange
中使用递归算法实现二叉树左右子树交换。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入: ABC##D##EF###
预期输出: 交换前二叉树中序遍历:C,B,D,A,F,E,
交换后二叉树中序遍历:E,F,A,D,B,C,
输入格式说明: 输入二叉树的先序序列。一棵二叉树的先序序列是一个字符串,若字符是‘#’,表示该二叉树是空树,否则该字符是相应结点的数据元素。
输出格式说明: 输出有两行: 第一行是交换前二叉树的中序遍历序列; 第二行是交换后的二叉树的中序遍历序列。
#include <stdio.h> #include <stdlib.h> #include "bitree.h" void exchange ( BiTree T ) ; // 实现二叉树左右子树的交换(递归法) int main() { BiTree T; CreateBiTree(T); printf("交换前二叉树中序遍历:"); InOrderTraverse(T,visit); printf("\n"); exchange(T); printf("交换后二叉树中序遍历:"); InOrderTraverse(T,visit); printf("\n"); DestoryBiTree(T); return 0; } void exchange ( BiTree T ) { // 实现二叉树左右子树的交换(递归法) /********** Begin *********/ BiTree temp; if(T){ temp=T->lchild; T->lchild=T->rchild; T->rchild=temp; exchange(T->lchild); exchange(T->rchild); } /********** End **********/ }
第5关:非递归实现二叉树左右子树交换
编程要求
本关的编程任务是补全右侧代码中
Begin
至End
中间的代码,具体要求如下:
- 在
exchange
中使用非递归算法实现二叉树左右子树交换。测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:
ABC##D##EF###
预期输出:交换前二叉树中序遍历:C,B,D,A,F,E,
交换后二叉树中序遍历:E,F,A,D,B,C,
输入格式说明: 输入二叉树的先序序列。一棵二叉树的先序序列是一个字符串,若字符是‘#’,表示该二叉树是空树,否则该字符是相应结点的数据元素。
输出格式说明: 输出有两行: 第一行是交换前二叉树的中序遍历序列; 第二行是交换后的二叉树的中序遍历序列。
#include <stdio.h> #include <stdlib.h> #include "bitree.h" #include "sqstack.h" void exchange ( BiTree T ) ; // 实现二叉树左右子树的交换(非递归法) int main() { BiTree T; CreateBiTree(T); printf("交换前二叉树中序遍历:"); InOrderTraverse(T,visit); printf("\n"); exchange(T); printf("交换后二叉树中序遍历:"); InOrderTraverse(T,visit); printf("\n"); DestoryBiTree(T); return 0; } void exchange(BiTree T) { // 实现二叉树左右子树的交换(栈实现) /********** Begin *********/ SqStack s; InitStack(s); Push(s,T); while(!StackEmpty(s)){ Pop(s,T); BiTree temp=T->lchild; T->lchild=T->rchild; T->rchild=temp; if(T->rchild) Push(s,T->rchild); if(T->lchild) Push(s,T->lchild); } DestroyStack(s); /********** End **********/ }
第6关:非递归实现二叉树的中序遍历
编程要求
根据提示,在右侧编辑器补充代码,实现下列函数:
InOrderTraverse(BiTree T,void(*Visit)(TElemType))
//中序非递归遍历二叉树T,对每个结点调用函数Visit一次且仅一次测试说明
平台会对你编写的代码进行测试:
测试输入:
ABD##FE###CG#H##I##
预期输出:
中序遍历为:D,B,E,F,A,G,H,C,I,
#include <stdio.h> #include <stdlib.h> #include "bitree.h" #include "sqstack.h" void InOrderTraverse2(BiTree T,void(*Visit)(TElemType));// 中序非递归遍历二叉树 int main() { BiTree T; CreateBiTree(T); printf("中序遍历:"); InOrderTraverse2(T,visit); printf("\n"); DestoryBiTree(T); return 0; } void InOrderTraverse2(BiTree T,void(*Visit)(TElemType)) { // 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。 // 中序遍历二叉树T的非递归算法,对每个数据元素调用函数Visit /********** Begin *********/ SqStack s; InitStack(s); while(T || !StackEmpty(s)){ if(T){ Push(s,T); T=T->lchild; }else{ Pop(s,T); Visit(T->data); T=T->rchild; } } DestroyStack(s); /********** End **********/ }