C++实现二叉树所有操作 -- 创建递归遍历迭代遍历拷贝清空查找

本文提供了一种使用C++实现二叉树的各种操作的方法,包括通过输入流、字符串创建二叉树,递归与迭代遍历,拷贝、查找、比较等。所有代码均经过测试验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文代码实现了二叉树输入流创建,字符串创建,带返回值的创建,前中后序递归及迭代遍历二叉树,拷贝二叉树,求大小,高度,查找元素,查找父节点,子节点,清空,比较等等二叉树所有操作。文中所有代码均经过测试。

#ifndef _BIN_TREE_H
#define _BIN_TREE_H

#include <iostream>
#include <vector>
#include <stack>
#include <assert.h>
#include <string.h>
using namespace::std;

template<typename _T>
class _Bin_Tree;

template<typename _T>
class _Tree_Node{
	friend class _Bin_Tree<_T>;
public:
	_Tree_Node() :m_data(_T()), leftChild(NULL), rightChild(NULL)
	{}
	_Tree_Node(_T data, _Tree_Node<_T>* left = NULL, _Tree_Node<_T>* right = NULL) 
				:m_data(data), leftChild(left), rightChild(left)
	{}
private:
	_T m_data;
	_Tree_Node<_T>  *leftChild;
	_Tree_Node<_T>  *rightChild;
};

template<typename _T>
class _Bin_Tree{
	typedef _Tree_Node<_T> node_type;
public:
	_Bin_Tree() = default;
	_Bin_Tree(const _T& ref) :refval(ref)
	{}
	_Bin_Tree(const _Bin_Tree<_T> &);
	~_Bin_Tree();
public:
	//create by cin/str 
	void init_bin_tree();
	node_type* init_tree_ret();   //has return value - root
	void init_bin_tree(const char *);
	node_type* init_tree_ret(const char *&);    //has return value - root

	//create by VLR-LVR   --   LVR-LRV
	void init_tree_pre_in(const char *, const char *);
	void init_tree_in_post(const char *, const char *); 

	//traverse  reverse/iter
	void preorder_traverse()const;
	void inorder_traverse()const;
	void postorder_traverse()const;
	void pre_iter_traverse()const;
	void in_iter_traverse()const;
	void post_iter_traverse()const;
	void level_traverse()const;
	
	size_t Size()const;
	size_t Height()const;
	node_type* Root()const;
	node_type* LeftChild(const node_type *)const;
	node_type* RightChild(const node_type *)const;
	node_type* Parent(const node_type *)const;
	node_type* Find(const _T &)const;
	bool Equal(const _Bin_Tree &)const;
	void make_empty();
protected:
	void init_bin_tree(node_type *&);
	node_type* init_tree_ret_();
	void init_bin_tree(node_type *&, const char *&);
	node_type* init_tree_ret_(const char *&);
	node_type* copy_tree(node_type *);
	
	void init_tree_pre_in(node_type *&, const char *, const char *, int);
	void init_tree_in_post(node_type *&, const char *, const char *, int); 

	void preorder_traverse(node_type *)const;
	void inorder_traverse(node_type *)const;
	void postorder_traverse(node_type *)const;
	void pre_iter_traverse(node_type *)const;
	void in_iter_traverse(node_type *)const;
	void post_iter_traverse(node_type *)const;
	void level_traverse(node_type *)const;
	
	size_t Size(node_type *)const;
	size_t Height(node_type *)const;
	node_type* Parent(node_type *, const node_type *)const;
	node_type* Find(node_type *, const _T &)const;
	bool Equal(node_type *, node_type *)const;
	void make_empty(node_type *);
private:
	_T refval;     //'#'
	node_type *root; 
};

/************************************public interface******************************************/

///

template<typename _T>
void _Bin_Tree<_T>::init_bin_tree()
{	
	init_bin_tree(root);
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::init_tree_ret()
{
	return root = init_tree_ret();
}

template<typename _T>
void _Bin_Tree<_T>::init_bin_tree(const char *str)
{
	init_bin_tree(root, str);
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::init_tree_ret(const char *&str)
{
	return root = init_tree_ret_(str);
}

template<typename _T>
_Bin_Tree<_T>::_Bin_Tree(const _Bin_Tree &bt)
{
	root = copy_tree(bt.root);
}

template<typename _T>
void _Bin_Tree<_T>::init_tree_pre_in(const char *VLR, const char* LVR)
{
	init_tree_pre_in(root, VLR, LVR, strlen(VLR));
}

template<typename _T>
void _Bin_Tree<_T>::init_tree_in_post(const char *LVR, const char *LRV)
{
	init_tree_in_post(root, LVR, LRV, strlen(LVR));
}
template<typename _T>
_Bin_Tree<_T>::~_Bin_Tree()
{
	make_empty();
	root = NULL;
}

///

template<typename _T>
void _Bin_Tree<_T>::preorder_traverse()const
{
	preorder_traverse(root);
}

template<typename _T>
void _Bin_Tree<_T>::inorder_traverse()const
{
	inorder_traverse(root);
}

template<typename _T>
void _Bin_Tree<_T>::postorder_traverse()const
{
	postorder_traverse(root);
}

template<typename _T>
void _Bin_Tree<_T>::pre_iter_traverse()const
{
	pre_iter_traverse(root);
}

template<typename _T>
void _Bin_Tree<_T>::in_iter_traverse()const
{
	in_iter_traverse(root);
}

template<typename _T>
void _Bin_Tree<_T>::post_iter_traverse()const
{
	post_iter_traverse(root);
}

template<typename _T>
void _Bin_Tree<_T>::level_traverse()const
{
	level_traverse(root);
}

///

template<typename _T>
size_t _Bin_Tree<_T>::Size()const
{
	return Size(root);
}

template<typename _T>
size_t _Bin_Tree<_T>::Height()const
{
	return Height(root);
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::Parent(const node_type *cur)const
{
	Parent(root, cur);
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::Find(const _T &key)const
{
	return Find(root, key);
}

template<typename _T>
bool _Bin_Tree<_T>::Equal(const _Bin_Tree<_T> &bt)const
{
	return Equal(root, bt.root);
}

template<typename _T>
void _Bin_Tree<_T>::make_empty()
{
	make_empty(root);
}


/***********************************protected interface****************************************/

///

template<typename _T>
void _Bin_Tree<_T>::init_bin_tree(node_type *&pt)
{
	_T elem;
	cin >> elem;

	if(refval == elem){
		pt = NULL;
	}
	else{
		pt = new node_type(elem);
		init_bin_tree(pt->leftChild);
		init_bin_tree(pt->rightChild);
	}
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::init_tree_ret_()
{
	node_type *pt;
	_T elem;

	cin >> elem;
	if(refval == elem){
		pt = NULL;
	}
	else{
		pt = new node_type(elem);
		pt->leftChild = init_tree_ret_();
		pt->rightChild = init_tree_ret_();
	}

	return pt;
}

template<typename _T>
void _Bin_Tree<_T>::init_bin_tree(node_type *&pt, const char *&str)
{
	if(*str == refval){
		pt = NULL;	
	}
	else{
		pt = new node_type(*str);
		init_bin_tree(pt->leftChild, ++str);
		init_bin_tree(pt->rightChild, ++str);
	}
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::init_tree_ret_(const char *&str)
{
	node_type *pt;

	if(*str == refval){
		pt = NULL;
	}
	else{
		pt = new node_type(*str);
		pt->leftChild = init_tree_ret_(++str);
		pt->rightChild = init_tree_ret_(++str);
	}

	return pt;
}

template<typename _T>
void _Bin_Tree<_T>::init_tree_pre_in(node_type *&pt, const char *VLR, const char *LVR, int len)
{
	if(len == 0){
		pt = NULL;
		return ;
	}
	else{
		int k = 0;
		while(LVR[k] != VLR[0])
			++k;
		
		pt = new node_type(LVR[k]);
		init_tree_pre_in(pt->leftChild, VLR+1, LVR, k);
		init_tree_pre_in(pt->rightChild, VLR+k+1, LVR+k+1, len-k-1);
	}
}

template<typename _T>
void _Bin_Tree<_T>::init_tree_in_post(node_type *&pt, const char *LVR, const char *LRV, int len)
{
	if(len == 0){
		pt = NULL;
		return ;
	}
	else{
		int k = 0;
		while(LVR[k] != LRV[len-1])
			k++;

		pt = new node_type(LVR[k]);
		init_tree_in_post(pt->leftChild, LVR, LRV, k);
		init_tree_in_post(pt->rightChild, LVR+k+1, LRV+k, len-k-1);
	}
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::copy_tree(node_type *pt)
{
	node_type *tmp;
	if(pt == NULL){
		return NULL;
	}
	else{
		tmp = new node_type(pt->m_data);
		tmp->leftChild = (copy_tree(pt->leftChild));
		tmp->rightChild = (copy_tree(pt->rightChild));
	}

	return tmp;
}

///

template<typename _T>
void _Bin_Tree<_T>::preorder_traverse(node_type *pt)const
{
	if(pt != NULL){
		cout << pt->m_data << " ";
		preorder_traverse(pt->leftChild);
		preorder_traverse(pt->rightChild);
	}
}

template<typename _T>
void _Bin_Tree<_T>::inorder_traverse(node_type *pt)const
{
	if(pt != NULL){
		inorder_traverse(pt->leftChild);
		cout << pt->m_data << " ";
		inorder_traverse(pt->rightChild);
	}
}

template<typename _T>
void _Bin_Tree<_T>::postorder_traverse(node_type *pt)const
{
	if(pt != NULL){
		postorder_traverse(pt->leftChild);
		postorder_traverse(pt->rightChild);
		cout << pt->m_data << " ";
	}
}

template<typename _T>
void _Bin_Tree<_T>::pre_iter_traverse(node_type *pt)const
{
	if(pt != NULL){
		stack<node_type*> st;
		node_type *tmp = NULL;

		st.push(pt);
		while(!st.empty()){
				tmp = st.top();
				st.pop();
			
				cout << tmp->m_data << " ";
			
				if(tmp->rightChild != NULL)
					st.push(tmp->rightChild);
				if(tmp->leftChild != NULL)
					st.push(tmp->leftChild);
		}
	}
}

template<typename _T>
void _Bin_Tree<_T>::in_iter_traverse(node_type *pt)const
{
	if(pt != NULL){
		stack<node_type*> st;
		node_type *tmp = pt;

		do{
			while(tmp != NULL){
				st.push(tmp);
				tmp = tmp->leftChild;
			}
			
			if(!st.empty()){
				tmp = st.top();
				st.pop();
			
				cout << tmp->m_data << " ";

				tmp = tmp->rightChild;
			}
		}while(tmp != NULL || !st.empty());
	}
}

//
//post_iter_traverse_1 -- struct
/*typedef enum{L, R}Tag;
template<typename _T>
struct Stknode{
	_Tree_Node<_T>* ptr;
	Tag tag;
	Stknode() :ptr(NULL), tag(L)
	{}
}; 
template<typename _T>
void _Bin_Tree<_T>::post_iter_traverse(node_type *pt)const
{
	Stknode<_T> stkn;
	node_type *tmp = pt;
	stack<Stknode<_T> > st;

	do{
		while(tmp != NULL){
			stkn.ptr = tmp;
			stkn.tag = L;

			st.push(stkn);
			tmp = tmp->leftChild;
		}

		bool isRun = true;
		while(isRun && !st.empty()){
			stkn = st.top();
			st.pop();
			
			switch(stkn.tag){
				case L:
					tmp = stkn.ptr;
					stkn.tag = R;
					st.push(stkn);
					tmp = tmp->rightChild;
					isRun = false;
					break;
				case R:
					cout << stkn.ptr->m_data << " ";
					break;
			}
		}
	}while(tmp != NULL || !st.empty());
}*/

//post_iter_traverse_2 -- pair
enum{L, R};
template<typename _T>
void _Bin_Tree<_T>::post_iter_traverse(node_type *pt)const
{
	if(pt != NULL){
		stack<pair<node_type*, int> > st;
		
		st.push(make_pair(pt, L));
		node_type* tmp;
		int tag;

		while(!st.empty()){
			tmp = st.top().first;
			tag = st.top().second;
				
			st.pop();
			if(tag == L){
				st.push(make_pair(tmp, R));
		
				if(tmp->rightChild != NULL)
					st.push(make_pair(tmp->rightChild, L));
				if(tmp->leftChild != NULL)
					st.push(make_pair(tmp->leftChild, L));
			}
			else{
				cout << tmp->m_data << " ";
			}
		}
	}
}

//

template<typename _T>
void _Bin_Tree<_T>::level_traverse(node_type *pt)const
{
	if(pt != NULL){
		vector<node_type *> vec;
		vec.push_back(root);

		int cur = 0;
		int end = 1;
	
		while(cur < vec.size()){
			end = vec.size();

			for( ; cur != end; ++cur){
				cout << vec[cur]->m_data << " ";

				if(vec[cur]->leftChild != NULL)
					vec.push_back(vec[cur]->leftChild);
				if(vec[cur]->rightChild != NULL)
					vec.push_back(vec[cur]->rightChild);
			}
		}	
	}
}

///

template<typename _T>
size_t _Bin_Tree<_T>::Size(node_type *pt)const
{
	if(pt == NULL)
		return 0;
	else
		return 1 + Size(pt->leftChild) + Size(pt->rightChild);
}

template<typename _T>
size_t _Bin_Tree<_T>::Height(node_type *pt)const
{
	if(pt == NULL)
		return 0;
	
	size_t left_height = Height(pt->leftChild);
	size_t right_height = Height(pt->rightChild);

	return (left_height > right_height ? left_height : right_height) + 1;	
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::Root()const
{
	return root;
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::LeftChild(const node_type *cur)const
{
	return cur->leftChild;
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::RightChild(const node_type *cur)const
{
	return cur->rightChild;
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::Parent(node_type *pt, const node_type *cur)const
{
	assert(cur != NULL);
	if(pt == NULL || cur == pt)
		return NULL;
	if(pt->leftChild == cur || pt->rightChild == cur)
		return pt;
	
	node_type* tmp = Parent(pt->leftChild, cur);
	if(tmp == NULL)
		tmp = Parent(pt->rightChild, cur);

	return tmp;
}

template<typename _T>
_Tree_Node<_T>* _Bin_Tree<_T>::Find(node_type *pt, const _T &key)const
{
	if(pt == NULL)
		return NULL;
	if(pt->m_data == key)
		return pt;
	
	node_type* tmp = Find(pt->leftChild, key);
	if(tmp == NULL)
		tmp = Find(pt->rightChild, key);
	
	return tmp;
}

template<typename _T>
bool _Bin_Tree<_T>::Equal(node_type *plhs, node_type *prhs)const
{
	if(plhs == NULL && prhs == NULL)
		return true;
	if(plhs != NULL && prhs != NULL && plhs->m_data == prhs->m_data
					&& Equal(plhs->leftChild, prhs->leftChild)
					&& Equal(plhs->rightChild, prhs->rightChild))
		return true;
	else
		return false;
}

template<typename _T>
void _Bin_Tree<_T>::make_empty(node_type *pt)
{
	if(pt != NULL){
		make_empty(pt->leftChild);
		make_empty(pt->rightChild);
		delete pt;
	}
}

///

#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值