BiTree.h
#ifndef BITREE_H
#define BITREE_H
#include<vector>
#include<iostream>
using namespace std;
template <class T>
struct BiNode
{ T data; // 结点数据
BiNode<T> *lchild; // 左孩子的指针
BiNode<T> *rchild; // 右孩子的指针
};
template <class T>
class BiTree
{ BiNode<T>* root; // 根指针
void PreOrder(BiNode<T> *p);
void InOrder(BiNode<T> *p);
void PostOrder(BiNode<T> *p);
BiNode<T>* CreateByPre(vector<T> &pre,int &i);
BiNode<T>* CreateByPreMid(vector<T> &pre, vector<T> &mid, int ipre, int imid,int n);
BiNode<T> * Copy(BiNode<T> *p);
void Free(BiNode<T> * p);
BiNode<T> *Search(BiNode<T> *p,T e);
BiNode<T> *SearchParent(BiNode<T> *p, BiNode<T>*child);
int Height(BiNode<T> *p);
int Count(BiNode<T> *p);
public:
BiTree() { root=NULL; }
BiTree(vector<T> &pre); // 由单个遍历序列构造对象
BiTree(vector<T> &pre,vector<T> &mid); // 由二个遍历序列构造对象
BiTree(BiTree<T> &tree); // 拷贝构造对象
~BiTree(); // 析构函数
void PreOrder(); // 先序遍历
void InOrder(); // 中序遍历
void PostOrder(); // 后序遍历
void LevelOrder(); // 层次遍历
int Count(); // 统计结点个数
int Height(); // 计算二叉树的高度
BiNode<T> *Search(T e); // 根据值e查找结点
BiNode<T> *SearchParent(BiNode<T>*child); // 查找指定结点的父结点
};
#endif
BiTree.cpp
#include<iostream>
#include"BiTree.h"
#include"SeqQueue.cpp"
#include<vector>
using namespace std;
template <class T>
void BiTree<T>::PreOrder(BiNode<T> *p)
{ if (p==NULL) return; // ①
cout << p->data; // ②
PreOrder(p->lchild); // ③
PreOrder(p->rchild); // ④
}
template <class T>
void BiTree<T>::PreOrder()
{ PreOrder(root); }
template <class T>
void BiTree<T>::InOrder(BiNode<T> *p)
{ if (p==NULL) return;
InOrder(p->lchild);
cout << p->data;
InOrder(p->rchild);
}
template <class T>
void BiTree<T>::InOrder()
{ InOrder(root); }
template <class T>
void BiTree<T>::PostOrder(BiNode<T> *p)
{ if (p==NULL) return;
PostOrder(p->rchild);
PostOrder(p->lchild);
cout << p->data;
}
template <class T>
void BiTree<T>::PostOrder()
{ PostOrder(root); }
template <class T>
void BiTree<T>::LevelOrder()
{
if(root==NULL) return; // ①若二叉树为空,遍历结束
SeqQueue<BiNode<T> *,100> Q;
Q.EnQueue(root); // ②将根指针加入指针队列
while(!Q.Empty()) // ③若指针队列不空,则循环
{
BiNode<T> * p=Q.DeQueue(); // ④出队列,得到当前指针p
cout<<p->data; // ④访问当前结点
// ⑤若p有左、右孩子,则左、右孩子地址进指针队列
if(p->lchild) Q.EnQueue(p->lchild);
if(p->rchild) Q.EnQueue(p->rchild);
}
}
template <class T>
BiTree<T>::BiTree(vector<T> &pre)
{ int i=0;
root=CreateByPre(pre,i);
}
template <class T>
BiNode<T> *BiTree<T>::CreateByPre(vector<T> &pre,int &i)
{ T e=pre[i]; i++; // 提取当前数据
if (e=='*') return NULL; // 特殊数据标记空指针
BiNode<T> *p=new BiNode<T>; p->data=e; // 创建新结点
p->lchild=CreateByPre(pre,i); // 创建左子树
p->rchild=CreateByPre(pre,i); // 创建右子树
return p;
}
template <class T>
BiTree<T>::BiTree(vector<T> &pre,vector<T> &mid)
{ int n=pre.size();
root=CreateByPreMid(pre,mid,0,0,n);
}
template <class T>
BiNode<T>* BiTree<T>::CreateByPreMid(vector<T> &pre, vector<T> &mid, int ipre, int imid,int n)
{ if(n==0) return NULL;
BiNode<T> *p = new BiNode<T>; p->data = pre[ipre];
// 创建新结点
for (int i=0; i<n; i++) // 在中序序列中定位根结点
if (pre[ipre]==mid[imid+i]) break;
p->lchild = CreateByPreMid(pre,mid,ipre+1, imid, i);
// 创建左子树
p->rchild = CreateByPreMid(pre,mid,ipre+i+1,imid+i+1,n-i-1);
// 创建右子树
return p;
}
template <class T>
BiNode<T> * BiTree<T>::Copy(BiNode<T> *p)
{
if(p==NULL) return NULL;
BinNode<T> *newp=new BinNode<T>; // 新建结点
newp->data=p->data;
newp->lchild= Copy(p->lchild); // 复制左子树
newp->rchild= Copy(p->rchild); // 复制右子树
return newp;
}
template <class T>
BiTree<T>::BiTree(BiTree<T> &tree)
{
root=Copy(tree.root);
}
template <class T>
int BiTree<T>::Count(BiNode<T> *p)
{
if (p==NULL) return 0;
int left= Count(p->lchild); // 计算左子树中的结点数
int right=Count(p->rchild); // 计算右子树中的结点数
return 1+left+right;
}
template <class T>
int BiTree<T>::Count()
{ return Count(root); }
template <class T>
int BiTree<T>::Height(BiNode<T> *p)
{ if (p==NULL) return 0;
int left =Height(p->lchild);
int right=Height(p->rchild);
if (left>right) return left+1;
return right+1;
}
template <class T>
int BiTree<T>::Height()
{ return Height(root); }
template <class T>
void BiTree<T>::Free(BiNode<T> * p)
{
if(p==NULL) return;
Free( p->lchild ); // 释放左子树
Free( p->rchild ); // 释放右子树
delete p; // 释放根结点
}
template <class T>
BiTree<T>::~BiTree()
{
Free(root);
}
template <class T>
BiNode<T> *BiTree<T>::Search(BiNode<T> *p,T e)
{
if (p==NULL) return(NULL);
if (p->data==e) return(p); // 查找成功
BiNode<T> *q=Search(p->lchild, e);
if (q) return q; // 若左子树中查找成功,则不再继续查找
return Search(p->rchild, e);
}
template <class T>
BiNode<T> *BiTree<T>::Search(T e)
{ return Search(root, e); }
template <class T>
BiNode<T> *BiTree<T>::SearchParent(BiNode<T> *p, BiNode<T>*child)
{
if (p==NULL || child==NULL) return NULL;
if (p->lchild==child || p->rchild==child) return p;
BiNode<T> *q=SearchParent(p->lchild, child);
if (q) return q;
return SearchParent(p->rchild, child);
}
template <class T>
BiNode<T> *BiTree<T>::SearchParent(BiNode<T>*child)
{ return SearchParent(root, child); }
SeqQueue.h
#ifndef SEQQUEUE_H
#define SEQQUEUE_H
template<class T,int MaxSize>
class SeqQueue
{
T data[MaxSize];
int front,rear;
public:
SeqQueue();
void EnQueue(T x);
T DeQueue();
T GetQueue();
bool Empty();
};
#endif
SeqQueue.cpp
#include<iostream>
#include"SeqQueue.h"
using namespace std;
template<class T,int MaxSize>
SeqQueue<T,MaxSize>::SeqQueue()
{
front=0;
rear=0;
}
template<class T,int MaxSize>
void SeqQueue<T,MaxSize>::EnQueue(T x)
{
if((rear+1)%MaxSize==front)
{
cerr<<"上溢";exit(1);
}
rear=(rear+1)% MaxSize;
data[rear]=x;
}
template<class T,int MaxSize>
T SeqQueue<T,MaxSize>::DeQueue()
{
if(rear==front)
{
cerr<<"下溢";exit(1);
}
front=(front+1)% MaxSize;
return data[front];
}
template<class T,int MaxSize>
T SeqQueue<T,MaxSize>::GetQueue()
{
if(rear==front)
{
cerr<<"下溢";exit(1);
}
int t;
t=(front+1)% MaxSize;
return data[t];
}
template<class T,int MaxSize>
bool SeqQueue<T,MaxSize>::Empty()
{
return rear==front;
}
main.cpp
#include<iostream>
#include"BiTree.cpp"
#include<vector>
using namespace std;
void main()
{
vector<char> a;
vector<char> b;
char c;
cout<<"请输入前序遍历树:(以*结束)"<<endl;
while(cin>>c)
{
if(c!='*')
a.push_back(c);
if(c=='*')
break;
}
cout<<"请输入中序遍历树:(以*结束)"<<endl;
while(cin>>c)
{
if(c!='*')
b.push_back(c);
if(c=='*')
break;
}
BiTree<char> t(a,b);
cout<<"前序遍历为:"<<endl;
t.PreOrder();
cout<<"中序遍历为:";t.InOrder();cout<<endl;
cout<<"后序遍历为:";t.PostOrder();cout<<endl;
cout<<"层序遍历为:";t.LevelOrder();cout<<endl;
cout<<"二叉树的节点数为:";t.Count();cout<<endl;
cout<<"二叉树的高度为:";t.Height();cout<<endl;
}