二叉树(C++类模板)

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;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
二叉树的顺序存储是将二叉树按照层次遍历的顺序存储在一个一维数组中,其中根节点存储在数组下标为1的位置,左子节点存储在2i的位置,右子节点存储在2i+1的位置(i为节点在数组中的下标)。 下面是一个使用类模板实现的二叉树顺序存储的示例代码: ```c++ #include <iostream> #include <vector> using namespace std; template <typename T> class SeqBinaryTree { public: SeqBinaryTree() {} SeqBinaryTree(const vector<T>& v); ~SeqBinaryTree() {} bool empty() const { return data_.empty(); } int size() const { return data_.size() - 1; } T root() const { return data_.at(1); } T parent(int i) const { return data_.at(i / 2); } T left(int i) const { return data_.at(2 * i); } T right(int i) const { return data_.at(2 * i + 1); } void insert(const T& value); void remove(int i); void print() const; private: vector<T> data_; }; template <typename T> SeqBinaryTree<T>::SeqBinaryTree(const vector<T>& v) { data_.resize(v.size() + 1); for (int i = 0; i < v.size(); ++i) { data_[i + 1] = v[i]; } } template <typename T> void SeqBinaryTree<T>::insert(const T& value) { data_.push_back(value); } template <typename T> void SeqBinaryTree<T>::remove(int i) { if (i < 1 || i > size()) { return; } data_.erase(data_.begin() + i); } template <typename T> void SeqBinaryTree<T>::print() const { for (int i = 1; i <= size(); ++i) { cout << data_[i] << " "; } cout << endl; } int main() { vector<int> v = { 1, 2, 3, 4, 5, 6, 7 }; SeqBinaryTree<int> tree(v); tree.insert(8); tree.print(); // 1 2 3 4 5 6 7 8 tree.remove(2); tree.print(); // 1 3 4 5 6 7 8 return 0; } ``` 在上面的代码中,SeqBinaryTree类模板包含了二叉树的一些基本操作,包括构造函数、判断是否为空、获取节点数目、获取根节点、获取父节点、获取左子节点、获取右子节点、插入节点、删除节点和打印二叉树。其中构造函数使用vector初始化二叉树,插入节点和删除节点都是在vector中进行操作,打印二叉树则是按照顺序输出vector中的元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈笑死哈哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值