【问题描述】
根据课程学习内容,补齐线性表的相关代码实现。
11 A B / / C D / / E / / C
上述输入将构造一棵包含11个节点的二叉树,并将查询“C”是否存在。
上述输入对应生成的二叉树如下图
【输入形式】
第一行:输入二叉树总节点数n,(空节点也计算在内)
第二行:以空格分隔的节点数据(string类型),其中 / 表示该节点为空,其他数据为该节点保存的信息
第三行:拟在二叉树中查询的值
【输出形式】
具体输出以提供的代码为准
【样例输入】
11 A B / / C D / / E / / C
【样例输出】
0:判断是否为空树:否 1:前序遍历:A B C D E 2:中序遍历:B A D C E 3:后序遍历:B D E C A 4:层次遍历:A B C D E 5:记录树的深度:2 6:记录树的高度:3 7:统计结点:5 8:统计叶子结点:3 9:查找C:存在 10:是否清空:已清空 5:记录树的深度:0 6:记录树的高度:0 7:统计结点:0 8:统计叶子结点:0
具体代码:
#include<iostream>
#include"string"
#include<queue>
using namespace std;
template<typename E>
class BinNode//结点类
{
private:
BinNode*lc;//左孩子
BinNode*rc;//右孩子
E elem;
public:
BinNode()//默认构造函数,设置左右孩子为空
{
lc=rc=NULL;
}
BinNode(E tmp, BinNode*l=NULL, BinNode*r=NULL)//带参构造函数
{
elem=tmp;
lc=l;
rc=r;
}
BinNode*left()//返回左孩子
{
return lc;
}
BinNode*right()//返回右孩子
{
return rc;
}
void setLeft(BinNode*l)//设置左孩子
{
lc=l;
}
void setRight(BinNode*r)//设置右孩子
{
rc=r;
}
void setValue(E tmp)//设置当前结点的值
{
elem=tmp;
}
E getValue()//获得当前结点的值
{
return elem;
}
bool isLeaf()//判断当前结点是否为叶子结点
{
return (lc==NULL)&&(rc==NULL);
}
};
template<typename E>
class BinTree//二叉树类
{
private:
BinNode<E>*root;//根结点
void clear(BinNode<E>*r)//清空二叉树
{
if(r==NULL) return;
clear(r->left());
clear(r->right());
delete r;
}
void preOrder(BinNode<E>*tmp,void(*visit)(BinNode<E>*node))//先序遍历,void(*visit)(BinNode<E>*node)为一个函数指针参数,用visit代替传进来的函数,在遍历函数中使用传进来的函数功能
{
if(tmp==NULL) return;
visit(tmp);
preOrder(tmp->left(),visit);
preOrder(tmp->right(),visit);
}
void inOrder( BinNode<E>*tmp,void(*visit)(BinNode<E>*node))//中序遍历,void(*visit)(BinNode<E>*node)为一个函数指针参数,用visit代替传进来的函数,在遍历函数中使用传进来的函数功能
{
if(tmp==NULL) return;
inOrder(tmp->left(),visit);
visit(tmp);
inOrder(tmp->right(),visit);
}
void postOrder(BinNode<E>*tmp,void(*visit)(BinNode<E>*node))//后序遍历,void(*visit)(BinNode<E>*node)为一个函数指针参数,用visit代替传进来的函数,在遍历函数中使用传进来的函数功能
{
if(tmp==NULL) return;
postOrder(tmp->left(),visit);
postOrder(tmp->right(),visit);
visit(tmp);
}
void LevelOrderTranverse( BinNode<E>*tmp,void(*visit)(BinNode<E>*node))//层次遍历,void(*visit)(BinNode<E>*node)为一个函数指针参数,用visit代替传进来的函数,在遍历函数中使用传进来的函数功能
{
BinNode<E>* temp;
queue<BinNode<E>*> q;
if(tmp==NULL) return;
q.push(tmp);
while(!q.empty()){
temp=q.front();
q.pop();
visit(temp);
if(temp->left()!=NULL) q.push(temp->left());
if(temp->right()!=NULL) q.push(temp->right());
}
}
int BinTreeDepth(BinNode<E>*tmp)//获得二叉树的深度
{
if(tmp==NULL) return 0;
else
return BinTreeHeight(tmp)-1;
}
int BinTreeNodes(BinNode<E>*tmp)//获得二叉树的结点数
{
if(tmp==NULL) return 0;
return 1+BinTreeNodes(tmp->left())+BinTreeNodes(tmp->right());
}
int BinTreeHeight(BinNode<E>*tmp)//获得二叉树的高度
{
if(tmp==NULL) return 0;
else
{
int m=BinTreeHeight(tmp->left());
int n=BinTreeHeight(tmp->right());
return (m > n) ? (m+1) : (n+1);
}
}
int BinTreeLeafs(BinNode<E>*tmp)//获得二叉树的叶子结点数
{
if(tmp==NULL) return 0;
if(tmp->left()==NULL&&tmp->right()==NULL) return 1;
else return BinTreeLeafs(tmp->left())+BinTreeLeafs(tmp->right());
}
bool find(BinNode<E>*tmp, E e)//查找二叉树中是否含有某个名为e的结点
{
BinNode<E>* temp;
queue<BinNode<E>*> q;
if(tmp==NULL) return false;
q.push(tmp);
while(!q.empty()){
temp=q.front();
q.pop();
if(temp->getValue()==e) return true;
if(temp->left()!=NULL) q.push(temp->left());
if(temp->right()!=NULL) q.push(temp->right());
}
return false;
}
public:
BinTree()//默认构造函数
{
root=new BinNode<E>;
}
~BinTree()//析构函数
{
clear(root);
}
bool BinTreeEmpty()//判断二叉树是否为空
{
if (root == NULL)
return true;
else
return false;
}
BinNode<E>*getRoot()//获得根节点
{
return root;
}
void setRoot(BinNode<E>*r)//设置根节点
{
root = r;
}
//下面的函数是对外的函数,所以内部还会有一些同名的函数,但是参数列表不一样,实现数据的封装,外部的调用不会涉及到内部的数据对象
void clear()//清空二叉树
{
clear(root);
root = NULL;
}
void preOrder(void(*visit)(BinNode<E>*node))//先序遍历,传入相对应的访问函数即可对该当前结点实现不同功能的访问(本程序为输出)
{
preOrder(root,visit);
}
void inOrder(void(*visit)(BinNode<E>*node)) //先序遍历,传入相对应的访问函数即可对该当前结点实现不同功能的访问(本程序为输出)
{
inOrder(root,visit);
}
void postOrder(void(*visit)(BinNode<E>*node))//先序遍历,传入相对应的访问函数即可对该当前结点实现不同功能的访问(本程序为输出)
{
postOrder(root,visit);
}
void LevelOrderTranverse(void(*visit)(BinNode<E>*node))//先序遍历,传入相对应的访问函数即可对该当前结点实现不同功能的访问(本程序为输出)
{
LevelOrderTranverse(root,visit);
}
int BinTreeDepth()//获得二叉树深度
{
return BinTreeDepth(root);
}
int BinTreeNodes()//获得二叉树结点数
{
return BinTreeNodes(root);
}
int BinTreeHeight()//获得二叉树高度
{
return BinTreeHeight(root);
}
int BinTreeLeafs()//获得二叉树叶子结点数
{
return BinTreeLeafs(root);
}
bool find(E e)//查找二叉树中是否存在名为e的结点
{
return find(root, e);
}
};