1.
任务描述
本关任务:给出一棵二叉树的括号表示法,本题要求实现3个函数,根据给出的括号表示法创建该二叉树并输出。输出时,也按二叉树的括号表示法输出。然后再求出二叉树高度并输出。
相关知识
二叉树的括号表示法如图所示:
上面5棵二叉树中,从左至右,每棵二叉树的括号表示法依次为:A,A(B,C),A(B(D),C),A(B(,D),C(E)),A(B(D,E),C(F,G))。
编程要求
代码窗口中给出了二叉树类型定义文件binary_tree.h和实现文件binary_tree.cpp。您的任务是根据提示,在右侧编辑器补充代码,完成给定的3个函数。函数声明如下:
// 利用二叉树的括号表示法创建二叉树root
// 参数:二叉树的根结点指针root。
// 参数:二叉树的括号表示法字符串s。
void CreateTree(BTNode* &root, ElemType* s);
//以嵌套括号表示法输出一棵树
void DispTree(BTNode* root);
// 求二叉树的高度
// 参数:二叉树根节点root
int getHeight(BTNode* root);
测试说明
平台会对你编写的代码进行测试:
输入样例1: A(B(D),C)
(对应二叉树如下)
输出样例1: A(B(D),C)
3
输入样例2: A(B(,D),C(E))
(对应二叉树如下)
输出样例2: A(B(,D),C(E))
3
#include "binary_tree.h"
//根据嵌套括号表示法的字符串生成链式存储的二叉树
void CreateTree(BTNode* &root, char str[]) {
/*请在BEGIN和END之间实现你的代码*/
/*****BEGIN*****/
BTNode* St[60], * p; root = NULL;
int top = -1, k, i = 0; //栈顶指针
char ch = str[i];
while (ch != '\0'){
switch (ch){
case '(':top++; St[top] = p; k = 1; break;
case ')':top--; break;
case ',': k = 2; break;
default:
p = (BTNode*)malloc(sizeof(BTNode));
p->data = ch;
p->lchild = p->rchild = NULL;
if (root == NULL)
root = p;
else{
k == 1 ? St[top]->lchild = p : St[top]->rchild = p;
}
}
ch = str[++i];
}
/******END******/
}
//以嵌套括号表示法输出一棵二叉树
void DispTree(BTNode* root) {
/*请在BEGIN和END之间实现你的代码*/
/*****BEGIN*****/
if (root != NULL){
printf("%c", root->data);
if (root->lchild != NULL || root->rchild != NULL){
printf("(");
DispTree(root->lchild);
if (root->rchild != NULL)
printf(",");
DispTree(root->rchild);
printf(")");
}
}
/******END******/
}
// 求二叉树的高度
// 参数:二叉树根节点root
int getHeight(BTNode* root)
{
/*请在BEGIN和END之间实现你的代码*/
/*****BEGIN*****/
int lchildh, rchildh;
if (root == NULL) return 0;
else{
lchildh = getHeight(root->lchild);
rchildh = getHeight(root->rchild);
return (lchildh > rchildh) ? (lchildh + 1) : (rchildh + 1);
}
/******END******/
}
2.
任务描述
本关任务:给定一棵二叉树,计算该二叉树的深度、总节点个数和叶子节点个数。
相关知识
为了完成本关任务,你需要掌握:1.二叉树深度概念,2.二叉树节点,3.二叉树叶子节点概念。
二叉树深度概念
二叉树的深度指的是二叉树中最大的结点层数。例如:图1
所示的二叉树最大的节点层数为3
,所以该二叉树深度为3
。
二叉树节点
二叉树的节点包含一个数据元素及两个指向子树的分支,例如:图1
所示的二叉树的总节点个数为6
。
二叉树叶子节点概念
叶子节点是度为0
的节点,二叉树节点的度为子树的个数。例如:图1
所示的二叉树叶子节点为C
,D
和F
,个数为3
。
编程要求
本关的编程任务是补全右侧代码片段GetTreeDepth
、GetNodeNumber
和GetLeafNodeNumber
中Begin
至End
中间的代码,具体要求如下:
- 在
GetTreeDepth
中计算该二叉树的深度,返回深度值。 - 在
GetNodeNumber
中计算该二叉树的总的节点个数,返回节点个数。 - 在
GetLeafNodeNumber
中计算该二叉树的叶子节点个数,返回叶子节点个数。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:ABC##D##EF###
预期输出: 3
6
3
测试输入:ABCD###E#F##G##
预期输出: 4
7
3
//
// binary_tree.cpp
#include "binary_tree.h"
//创建新结点的工具函数
BTNode* getNewNode(char e)
{
BTNode* p = (BTNode*)malloc(sizeof(BTNode));
p->data = e;
p->lchild = p->rchild = NULL;
return p;
}
// 计算该二叉树的深度
// 参数:二叉树根节点root
// 返回:二叉树的深度
int GetTreeDepth(BTNode* root)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
if(root==NULL) return 0;
else if(root->rchild==NULL&&root->lchild==NULL)return 1;
int r=GetTreeDepth(root->rchild);
int l=GetTreeDepth(root->lchild);
int e=(r>l?r:l);
return 1+e;
/********** End **********/
}
// 计算该二叉树的总节点个数
// 参数:二叉树根节点root
// 返回:二叉树的总节点个数
int GetNodeNumber(BTNode* root)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
if(root==NULL) return 0;
else if(root->rchild==NULL&&root->lchild==NULL)return 1;
int r=GetNodeNumber(root->rchild);
int l=GetNodeNumber(root->lchild);
return r+l+1;
/********** End **********/
}
// 计算该二叉树的叶子节点个数
// 参数:二叉树根节点root
// 返回:二叉树的叶子节点个数
int GetLeafNodeNumber(BTNode* root)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
if(root==NULL) return 0;
else if(root->rchild==NULL&&root->lchild==NULL)return 1;
int r=GetLeafNodeNumber(root->rchild);
int l=GetLeafNodeNumber(root->lchild);
return r+l;
/********** End **********/
}
3.
任务描述
本关任务:给定一棵二叉树,使用递归和非递归的方法实现二叉树的先(前)序遍历结果。
相关知识
为了完成本关任务,你需要掌握:1.递归算法,2.二叉树左右子树性质,3.二叉树先序遍历。
递归法
递归算法recursion algorithm
在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。其核心是将原始问题转化为子问题。 例如:计算n
阶乘的程序在数学上可以定义为:
fact(n)={1n×fact(n−1)n=0n>0
则递归算法求n
阶乘的伪代码为:
int fact(int n){
if(n == 0)
return 1;
else
return n * fact(n - 1);
}
二叉树左右子树性质
二叉树的每个节点最多只有两个分支,通常分支被称作左子树和右子树,并且二叉树的分支具有左右次序,不能颠倒。图1
是一棵二叉树。
编程要求
本关的编程任务是补全右侧代码片段PreOrder
和PreOrder_iter
中Begin
至End
中间的代码,具体要求如下:
- 在
PreOrder
中使用递归算法实现二叉树先序遍历递归算法并输出结果,中间没有空格,末尾不换行。 - 在
PreOrder_iter
中实现二叉树的先序遍历非递归算法并输出结果,中间没有空格,末尾不换行。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:ABC##D##EF###
预期输出: AEFBDC
AEFBDC
测试输入:ABCD###E#F##G##
预期输出: AGBEFCD
AGBEFCD
//
// binary_tree.cpp
#include "binary_tree.h"
// 二叉树的前序遍历
// 参数:二叉树根节点root
// 输出:二叉树的前序遍历,中间没有空格,末尾不换行。
void PreOrder(BTNode* root)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
if(root!=NULL)
{printf("%c",root->data);
PreOrder(root->lchild);
PreOrder(root->rchild);}
/********** End **********/
}
// 二叉树的前序遍历非递归算法
// 参数:二叉树根节点root
// 输出:二叉树的前序遍历,中间没有空格,末尾不换行。
void PreOrder_iter(BTNode* root)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
BTNode *St[100000],*p;
int top=-1;
if(root!=NULL)
{
top++;
St[top]=root;
while(top>-1)
{
p=St[top];
top--;
printf("%c",p->data);
if(p->rchild!=NULL)
{
top++;
St[top]=p->rchild;
}
if(p->lchild!=NULL)
{
top++;
St[top]=p->lchild;
}
}
printf("\n");}
/********** End **********/
}
4.
任务描述
本关任务:给定一棵二叉树,使用递归和非递归的方法实现二叉树的中序遍历结果。
相关知识
为了完成本关任务,你需要掌握:1.递归算法,2.二叉树左右子树性质,3.二叉树中序遍历。
递归法
递归算法recursion algorithm
在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。其核心是将原始问题转化为子问题。 例如:计算n
阶乘的程序在数学上可以定义为:
fact(n)={1n×fact(n−1)n=0n>0
则递归算法求n
阶乘的伪代码为:
int fact(int n){
if(n == 0)
return 1;
else
return n * fact(n - 1);
}
二叉树左右子树性质
二叉树的每个节点最多只有两个分支,通常分支被称作左子树和右子树,并且二叉树的分支具有左右次序,不能颠倒。图1
是一棵二叉树。
编程要求
本关的编程任务是补全右侧代码片段InOrder
和InOrder_iter
中Begin
至End
中间的代码,具体要求如下:
- 在
InOrder
中使用递归算法实现二叉树中序遍历递归算法并输出结果,中间没有空格,末尾不换行。 - 在
InOrder_iter
中实现二叉树的中序遍历非递归算法并输出结果,中间没有空格,末尾不换行。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:ABC##D##EF###
预期输出: CBDAFE
CBDAFE
测试输入:ABCD###E#F##G##
预期输出: DCBEFAG
DCBEFAG
//
// binary_tree.cpp
#include "binary_tree.h"
// 二叉树的中序遍历
// 参数:二叉树根节点root
// 输出:二叉树的中序遍历,中间没有空格,末尾不换行。
void InOrder(BTNode* root)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
if(root!=NULL){
InOrder(root->lchild);
printf("%c",root->data);
InOrder(root->rchild)
/********** End **********/
}
// 二叉树的中序遍历非递归算法
// 参数:二叉树根节点root
// 输出:二叉树的中序遍历,中间没有空格,末尾不换行。
void InOrder_iter(BTNode* root)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
BTNode *St[100000],*p;
int top=-1;
if(root!=NULL)
{
p=root;
while(top>-1||p!=NULL)
{
while(p!=NULL)
{
top++;
St[top]=p;
p=p->lchild;
}
if(top>-1)
{
p=St[top];
top--;
printf("%c",p->data);
p=p->rchild;
}
}
printf("\n");
}
/********** End **********/
}
5.任务描述
本关任务:给定一棵二叉树,借助队列实现层次遍历二叉树。
相关知识
为了完成本关任务,你需要掌握:1.队列基本操作,2.二叉树层次遍历。
队列基本操作
本关卡提供C++ STL
模板队列queue
的相关操作和功能。
- 使用实例如下:
queue<int> q; // 创建队列对象
q.push(3); // 元素入队列
q.push(4);
cout<<q.size()<<endl; //打印队列元素个数
while(!q.empty()) {
cout<<q.front()<<endl; // 打印队首元素
q.pop(); // 移除队首元素
}
二叉树层次遍历
层次遍历要求先访问离根节点最近的层的节点,然后依次访问下一层的节点。例如:图1
的层次遍历顺序为节点上的数字,结果为:ABECDF
。
编程要求
本关的编程任务是补全右侧代码片段LevelOrder
中Begin
至End
中间的代码,具体要求如下:
- 在
LevelOrder
中实现二叉树的层次遍历并输出结果,中间没有空格,末尾不换行。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:ABC##D##EF###
预期输出:ABECDF
测试输入:ABCD###E#F##G##
预期输出:ABGCEDF
//
// binary_tree.cpp
#include "binary_tree.h"
// 二叉树的层次遍历(队列实现)
// 参数:二叉树根节点root
// 输出:二叉树的层次遍历,中间没有空格,末尾不换行。
void LevelOrder(BTNode* root)
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
BTNode* Queue[100];
int front,rear;
if(root==NULL)return;
front=-1;rear=0;
Queue[rear]=root;
while(front!=rear)
{
front++;
printf("%c",Queue[front]->data);
if(Queue[front]->lchild!=NULL)
{
rear++;
Queue[rear]=Queue[front]->lchild;
}
if(Queue[front]->rchild!=NULL)
{
rear++;
Queue[rear]=Queue[front]->rchild;
}
}
/********** End **********/
}