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