目的:使用C++模板设计并逐步完善二叉树的抽象数据类型(ADT)。
内容:(1)请参照链表的ADT模板,设计二叉树并逐步完善的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的链表ADT原型文件,自行设计二叉树的ADT。)
注意:二叉树ADT的基本操作的算法设计很多要用到递归的程序设计方法。
(2)基本操作:在二叉树的二叉链表存储形式建立的基础上,设计二叉树的三种遍历算法:前序、中序和后序。完成后将它们加入到二叉树的ADT基本操作集中。
要求使用递归的程序设计方法,设计并完成二叉树的三种遍历算法。
初始条件:二叉树T存在,visit是对结点操作的应用函数。
操作结果:先序(中序、后序)遍历T,对每个结点调用函数visit一次且仅一次。一旦visit()失败,则操作失败。
参考函数原型:
(1)visit函数(具体功能根据实际需要,样例仅仅输出data域的信息)
template<class ElemType>
bool visit(BinaryTreeNode<ElemType> * root, int &num){
if(!root) return false;
else{
if(num==0){//控制输出格式
cout<<root->data;
num++;
}
else cout<<","<<root->data;
return true;
}
}
(2)基本操作2:前序遍历
//前序遍历(外壳部分,用户函数)
template<class ElemType>
bool PreOrderTraverse(BinaryTree<ElemType> &T);
//前序遍历(递归部分,成员函数)
template<class ElemType>
bool BinaryTree<ElemType>::PreOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;
(3)基本操作3:中序遍历
//中序遍历(外壳部分,用户函数)
template<class ElemType>
bool InOrderTraverse(BinaryTree<ElemType> &T);
//中序遍历(递归部分,成员函数)
template<class ElemType>
bool BinaryTree<ElemType>::InOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;
(4)基本操作4:后序遍历
//后序遍历(外壳部分,用户函数)
template<class ElemType>
bool PostOrderTraverse(BinaryTree<ElemType> &T);
//后序遍历(递归部分,成员函数)
template<class ElemType>
bool BinaryTree<ElemType>::PostOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;
感觉这种用抽象数据类型的比直接用函数麻烦好多,不过题目要求用ADT的话就慢慢写啦~
话不多说,上代码:
#include<iostream>
#include<cstring>
#include<vector>
#include<sstream>
using namespace std;
/* 二叉表的结点定义 */
template<class ElemType>
struct BinaryTreeNode
{
ElemType data;
BinaryTreeNode<ElemType> *LChild, *RChild;
BinaryTreeNode() : LChild(NULL), RChild(NULL) {} //构造函数1,用于构造根结点
BinaryTreeNode(const ElemType &item, BinaryTreeNode<ElemType> *Lptr = NULL, BinaryTreeNode<ElemType> *Rptr = NULL) //构造函数2,用于构造其他结点
//函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面
{
LChild = Lptr;
RChild = Rptr;
data = item;
}
ElemType getData()
{
return data; //取得结点中的数据
}
void SetLChild( BinaryTreeNode<ElemType> *link )
{
LChild = link; //修改结点的左孩子域
}
void SetRChild( BinaryTreeNode<ElemType> *link )
{
RChild = link; //修改结点的右孩子域
}
void SetData( ElemType value )
{
data = value; //修改结点的data域
}
BinaryTreeNode<ElemType> * GetLChild() const
{
return LChild; //获取左孩子结点
}
BinaryTreeNode<ElemType> * GetRChild() const
{
return RChild; //获取左孩子结点
}
};
template<class ElemType>
bool visit(BinaryTreeNode<ElemType> *root,int &num)
{
if(!root)
return false;
else
{
if(num==0)
{
cout<<root->data;
num++;
}
else
cout<<","<<root->data;
return true;
}
}
//二叉树
template<class ElemType>
class BinaryTree
{
private:
BinaryTreeNode<ElemType> *root; // 头指针
void BinaryTreeDestroy_Cursive( BinaryTreeNode<ElemType> *T ); //销毁树(递归准备,private)
public:
//无参数的构造函数
BinaryTree():root(NULL) {}
//带参数的构造函数
BinaryTree(const ElemType &item)
{
root = new BinaryTreeNode<ElemType>(item);
}
//生成树
void makeBinaryTree( const ElemType &item, BinaryTree &left, BinaryTree &right);
//拷贝构造函数
//LinkQueue(LinkQueueList<ElemType> &Queue);
//析构函数
//~BinaryTree()
//{
// BinaryTreeDestroy();
//}
//重载函数:赋值
//LinkList<ElemType>& operator=(LinkList<ElemType> &List);
//销毁树
void BinaryTreeDestroy();
//销毁子树
void ChildDestroy(int flag);
//返回二叉树结点的个数
int BinaryTreeSize( BinaryTreeNode<ElemType> *T ) const;
//判断二叉树是否为空
bool BinaryTreeisEmpty() const
{
return root == NULL;
}
//获取根结点元素值
ElemType GetRootData() const
{
return root->data;
}
//bool Location(ElemType &x, BinaryTreeNode<ElemType> * &location);
//设置根结点
void SetRoot(BinaryTreeNode<ElemType> * p)
{
root = p;
}
//获取根结点
BinaryTreeNode<ElemType> * GetRoot() const
{
return root;
}
//前序遍历
bool Pre(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const; //前序遍历(递归)//num的初始值为0,作用为控制输出格式(最后1个结点后不加“,”)
//中序遍历
bool In(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const; //中序遍历(递归)
//后序遍历
bool Post(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const; //后序遍历(递归)
//建立二叉树的存储结构
BinaryTreeNode<ElemType>* CreateBinaryTree(vector<ElemType> &x, ElemType &sym, int &n);
};
//建立二叉树的存储结构 (递归部分,成员函数)
template<class ElemType>
BinaryTreeNode<ElemType>* BinaryTree<ElemType>::CreateBinaryTree(vector<ElemType> &x, ElemType &sym, int &n)
{
ElemType ch = x[n];
n++;
if (ch == sym)
{
return NULL;
}
else
{
BinaryTreeNode<ElemType> *Node = new BinaryTreeNode<ElemType>;
Node->data = ch;
Node->LChild = CreateBinaryTree(x, sym, n);
Node->RChild = CreateBinaryTree(x, sym, n);
return Node;
}
}
//建立二叉树的存储结构 (外壳)
template<class ElemType>
void CreateTree(BinaryTree<ElemType> &T, ElemType &str, ElemType &sym)
{
ElemType tmp;
vector<ElemType> t;
stringstream input_T(str);
while(input_T>>tmp)
{
t.push_back(tmp);
}
BinaryTreeNode<ElemType> *root;
int num=0;
root=T.CreateBinaryTree(t,sym,num);
T.SetRoot(root);
}
template<class ElemType>
void BinaryTree<ElemType>::makeBinaryTree(const ElemType &item, BinaryTree &left, BinaryTree &right)
{
root=new BinaryTreeNode<ElemType>(item,left.root,right.root);
left.root=NULL;
right.root=NULL;
}
//前序遍历
template<class ElemType>
bool BinaryTree<ElemType>::Pre(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const
{
//成员函数,递归
if(T==NULL)
return false;
visit(T,num);
Pre(T->LChild,visit,num);
Pre(T->RChild,visit,num);
}
template<class ElemType>
bool Pre(BinaryTree<ElemType> &T)
{
//用户函数
BinaryTreeNode<ElemType> *p=T.GetRoot();
int num=0;
T.Pre(p,visit,num);
}
//中序遍历
template<class ElemType>
bool BinaryTree<ElemType>::In(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const
{
//成员函数,递归
if(T==NULL)
return false;
In(T->LChild,visit,num);
visit(T,num);
In(T->RChild,visit,num);
}
template<class ElemType>
bool In(BinaryTree<ElemType> &T)
{
//用户函数
BinaryTreeNode<ElemType> *p=T.GetRoot();
int num=0;
T.In(p,visit,num);
}
//后序遍历
template<class ElemType>
bool BinaryTree<ElemType>::Post(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const
{
//成员函数,递归
if(T==NULL)
return false;
Post(T->LChild,visit,num);
Post(T->RChild,visit,num);
visit(T,num);
}
template<class ElemType>
bool Post(BinaryTree<ElemType> &T)
{
//用户函数
BinaryTreeNode<ElemType> *p=T.GetRoot();
int num=0;
T.Post(p,visit,num);
}
int main()
{
BinaryTree<string>BT;
string mytree;
string sym;
getline(cin,sym);
getline(cin,mytree);
CreateTree(BT,mytree,sym);
Pre(BT);
cout<<endl;
In(BT);
cout<<endl;
Post(BT);
return 0;
}
这样用这个模板,然后后面二叉树抽象数据类型的挺多题目应该可以套用,所以应该是挺有用滴。
嘿嘿,int main 里的前面几句话最好记住哦。我的第一篇博客,谢谢支持!