#ifndef BINNODE_H
#define BINNODE_H
#include <queue>
#include <stack>
#include <vector>
namespace Shawn
{
template <typename _T>
class BinNode
{
template<typename _T> friend class BinTree;
template<typename _T, typename _VST>
friend void travPre(typename BinNode<_T>::_BinNodePtr _x, _VST& _visit);
template<typename _T, typename _VST>
friend void travIn(typename BinNode<_T>::_BinNodePtr _x, _VST& _visit);
template<typename _T, typename _VST>
friend void travPost(typename BinNode<_T>::_BinNodePtr _x, _VST& _visit);
template<typename _T>
friend typename BinNode<_T>::_BinNodePtr reconstruction_pre_in(const size_t _n,
const std::vector<_T>& _pre, const std::vector<_T>& _in);
template<typename _T>
friend typename BinNode<_T>::_BinNodePtr reconstruction_post_in(const size_t _n,
const std::vector<_T>& _post, const std::vector<_T>& _in);
protected:
typedef BinNode<_T>* _BinNodePtr;
_T _data;
_BinNodePtr _parent, _lc, _rc;
size_t _height;
public:
BinNode() : _parent(nullptr), _lc(nullptr), _rc(nullptr), _height(0) { }
BinNode(_T _e, _BinNodePtr _p = nullptr, _BinNodePtr _lc = nullptr, _BinNodePtr _rc = nullptr,
size_t _h = 0) : _data(_e), _parent(_p), _lc(_lc), _rc(_rc), _height(_h) { }
public:
size_t size();
size_t stature()
{
return this ? this->_height : -1;
}
_BinNodePtr insertAsLC(_T const&);
_BinNodePtr insertAsRC(_T const&);
_BinNodePtr succ();
template<typename _VST> void travLevel(_VST&);
template<typename _VST> void travPre(_VST&);
template<typename _VST> void travIn(_VST&);
template<typename _VST> void travPost(_VST&);
template < typename _VST>
static void _travPre_aux(_BinNodePtr _x, _VST& _visit, std::stack<_BinNodePtr>& _S)
{
while (_x)
{
_visit(_x->_data);
if (_x->_rc) _S.push(_x->_rc);
_x = _x->_lc;
}
}
static void _travIn_aux(_BinNodePtr _x, std::stack<_BinNodePtr>& _S)
{
while (_x) { _S.push(_x); _x = _x->_lc; }
}
static void _travPost_aux(std::stack<_BinNodePtr>& _S)
{
while (_BinNodePtr _x = _S.top())
{
if (_x->_lc)
{
if (_x->_rc) _S.push(_x->_rc);
_S.push(_x->_lc);
}
else
{
_S.push(_x->_rc);
}
}
_S.pop();
}
bool operator== (BinNode const& _bn) { return _data == _bn._data; }
bool operator!= (BinNode const& _bn) { return !(*this == _bn); }
bool operator< (BinNode const& _bn) { return _data < _bn._data; }
bool operator> (BinNode const& _bn) { return _bn < *this; }
bool operator<= (BinNode const& _bn) { return !(_bn < *this); }
bool operator>= (BinNode const& _bn) { return !(*this < _bn); }
};
template<typename _T>
size_t BinNode<_T>::size()
{
size_t _tmp = 1;
if (_lc) size_t _tmp += _lc->size();
if (_rc) size_t _tmp += _rc->size();
return _tmp;
}
template<typename _T>
typename BinNode<_T>::_BinNodePtr BinNode<_T>::insertAsLC(_T const& _e)
{
return _lc = new BinNode(_e, this);
}
template<typename _T>
typename BinNode<_T>::_BinNodePtr BinNode<_T>::insertAsRC(_T const& _e)
{
return _rc = new BinNode(_e, this);
}
template <typename _T>
typename BinNode<_T>::_BinNodePtr BinNode<_T>::succ()
{
_BinNodePtr _tmp = this;
if (_rc)
{
_tmp = _rc;
while (_tmp->_lc) _tmp = _tmp->_lc;
}
else
{
while (_tmp->_parent && _tmp->_parent->_rc == _tmp)
_tmp = _tmp->_parent;
_tmp = _tmp->_parent;
}
return _tmp;
}
template<typename _T>
template<typename _VST>
void BinNode<_T>::travLevel(_VST& _visit)
{
std::queue<_BinNodePtr> Q;
Q.push(this);
while (!Q.empty())
{
_BinNodePtr _x = Q.front(); Q.pop(); _visit(_x->_data);
if (_x->_lc) Q.push(_x->_lc);
if (_x->_rc) Q.push(_x->_rc);
}
}
template<typename _T>
template<typename _VST>
void BinNode<_T>::travPre(_VST& _visit)
{
stack<_BinNodePtr> _S;
_BinNodePtr _tmp = this;
while (true)
{
_travPre_aux(_tmp, _visit, _S);
if (_S.empty()) break;
_tmp = _S.top();
_S.pop();
}
}
template<typename _T>
template<typename _VST>
void BinNode<_T>::travIn(_VST& _visit)
{
std::stack<_BinNodePtr> _S;
_BinNodePtr _tmp = this;
while (true)
{
_travIn_aux(_tmp, _S);
if (_S.empty()) break;
_tmp = _S.top(); _S.pop(); _visit(_tmp->_data);
_tmp = _tmp->_rc;
}
}
template <typename _T>
template<typename _VST>
void BinNode<_T>::travPost(_VST& _visit)
{
std::stack<_BinNodePtr> _S;
if (this) _S.push(this);
_BinNodePtr _tmp = this;
while (!_S.empty())
{
if (_S.top() != _tmp->_parent)
_travPost_aux(_S);
_tmp = _S.top(); _S.pop(); _visit(_tmp->_data);
}
}
template<typename _T, typename _VST>
inline
void travPre(typename BinNode<_T>::_BinNodePtr _x, _VST & _visit)
{
if (!_x) return;
_visit(_x->_data);
travPre<_T>(_x->_lc, _visit);
travPre<_T>(_x->_rc, _visit);
}
template<typename _T, typename _VST>
inline
void travIn(typename BinNode<_T>::_BinNodePtr _x, _VST & _visit)
{
if (!_x) return;
travIn<_T>(_x->_lc, _visit);
_visit(_x->_data);
travIn<_T>(_x->_rc, _visit);
}
template<typename _T, typename _VST>
inline
void travPost(typename BinNode<_T>::_BinNodePtr _x, _VST & _visit)
{
if (!_x) return;
travPost<_T>(_x->_lc, _visit);
travPost<_T>(_x->_rc, _visit);
_visit(_x->_data);
}
template<typename _T>
typename BinNode<_T>::_BinNodePtr reconstruction_pre_in(const size_t _n,
const std::vector<_T>& _pre, const std::vector<_T>& _in)
{
if (_pre.size() != _in.size() || _n <= 0)
{
return nullptr;
}
typename BinNode<_T>::_BinNodePtr _root = new BinNode<_T>(_pre[0]);
size_t _index = 0;
for (; _index != _n; ++_index)
{
if (_pre[0] == _in[_index])
{
break;
}
}
if (_index < 0 || _index >= _n)
{
exit(1);
}
vector<_T> _left_tree_pre, _left_tree_in, _right_tree_pre, _right_tree_in;
for (size_t _i = 0; _i < _index; _i++)
{
_left_tree_pre.push_back(_pre[_i + 1]);
_left_tree_in.push_back(_in[_i]);
}
for (size_t _i = _index + 1; _i < _in.size(); _i++)
{
_right_tree_pre.push_back(_pre[_i]);
_right_tree_in.push_back(_in[_i]);
}
_root->_lc = reconstruction_pre_in(_left_tree_pre.size(), _left_tree_pre, _left_tree_in);
_root->_rc = reconstruction_pre_in(_right_tree_pre.size(), _right_tree_pre, _right_tree_in);
return _root;
}
template<typename _T>
typename BinNode<_T>::_BinNodePtr reconstruction_post_in(const size_t _n, const std::vector<_T>& _post, const std::vector<_T>& _in)
{
if (_post.size() != _in.size() || _n <= 0)
{
return nullptr;
}
typename BinNode<_T>::_BinNodePtr _root = new BinNode<_T>(_post[_n-1]);
size_t _index = 0;
for (; _index != _n; ++_index)
{
if (_post[_n - 1] == _in[_index])
{
break;
}
}
if (_index < 0 || _index >= _n)
{
return nullptr;
}
vector<_T> _left_tree_post, _left_tree_in, _right_tree_post, _right_tree_in;
for (size_t _i = 0; _i != _index; _i++)
{
_left_tree_post.push_back(_post[_i]);
_left_tree_in.push_back(_in[_i]);
}
for (size_t _i = _index + 1; _i != _in.size(); _i++)
{
_right_tree_post.push_back(_post[_i-1]);
_right_tree_in.push_back(_in[_i]);
}
_root->_lc = reconstruction_post_in(_left_tree_post.size(), _left_tree_post, _left_tree_in);
_root->_rc = reconstruction_post_in(_right_tree_post.size(), _right_tree_post, _right_tree_in);
return _root;
}
}
#endif
#ifndef BINTREE_H
#define BINTREE_H
#include "BinNode.h"
#include <functional>
namespace Shawn
{
template <typename _T>
class BinTree
{
typedef BinNode<_T>* _BinNodePtr;
size_t _size; _BinNodePtr _root;
virtual size_t _updateHeight(_BinNodePtr _x);
void _updateHeightAbove(_BinNodePtr _x);
public:
BinTree() : _size(0), _root(nullptr) { }
~BinTree() { if (0 < _size) remove(_root); }
size_t size() const { return _size; }
bool empty() const { return !_root; }
_BinNodePtr root() const { return _root; }
_BinNodePtr insertAsRoot(_T const& _e);
_BinNodePtr insertAsLC(_BinNodePtr _x, _T const& _e);
_BinNodePtr insertAsRC(_BinNodePtr _x, _T const& _e);
_BinNodePtr attachAsLC(_BinNodePtr _x, BinTree<_T>*& _T);
_BinNodePtr attachAsRC(_BinNodePtr _x, BinTree<_T>*& _T);
size_t remove(_BinNodePtr _x);
size_t removeAt(_BinNodePtr _x);
template <typename _VST>
void travLevel(_VST& _visit) { if (_root) _root->travLevel(_visit); }
template <typename _VST>
void travPre(_VST& _visit) { if (_root) _root->travPre(_visit); }
template <typename _VST>
void travIn(_VST& _visit) { if (_root) _root->travIn(_visit); }
template <typename _VST>
void travPost(_VST& _visit) { if (_root) _root->travPost(_visit); }
public:
bool operator< (BinTree<_T> const& _t)
{
return _root && _t._root && std::less<_T>(_root, _t._root);
}
bool operator== (BinTree<_T> const& _t)
{
return _root && _t._root && (_root == _t._root);
}
};
template <typename _T>
size_t BinTree<_T>::_updateHeight(_BinNodePtr _x)
{
return _x->_height = 1 + max(_x->_lc->stature(), _x->_rc->stature());
}
template <typename _T>
void BinTree<_T>::_updateHeightAbove(_BinNodePtr _x)
{
while (_x) { _updateHeight(_x); _x = _x->_parent; }
}
template <typename _T>
typename BinTree<_T>::_BinNodePtr BinTree<_T>::insertAsRoot(_T const& _e)
{
_size = 1; return _root = new BinNode<_T>(_e);
}
template <typename _T>
typename BinTree<_T>::_BinNodePtr BinTree<_T>::insertAsLC(_BinNodePtr _x, _T const& _e)
{
++_size;
_x->insertAsLC(_e);
_updateHeightAbove(_x);
return _x->_lc;
}
template <typename _T>
typename BinTree<_T>::_BinNodePtr BinTree<_T>::insertAsRC(_BinNodePtr _x, _T const& _e)
{
++_size;
_x->insertAsRC(_e);
_updateHeightAbove(_x);
return _x->_rc;
}
template <typename _T>
typename BinTree<_T>::_BinNodePtr BinTree<_T>::attachAsLC(_BinNodePtr _x, BinTree<_T>*& _S)
{
if (_x->_lc = _S->_root) _x->_lc->_parent = _x;
_size += _S->_size; _updateHeightAbove(_x);
_S->_root = nullptr; _S->_size = 0; _S = nullptr; return _x;
}
template <typename _T>
typename BinTree<_T>::_BinNodePtr BinTree<_T>::attachAsRC(_BinNodePtr _x, BinTree<_T>*& _S)
{
if (_x->_rc = _S->_root) _x->_rc->_parent = _x;
_size += _S->_size; _updateHeightAbove(_x);
_S->_root = nullptr; _S->_size = 0; _S = nullptr; return _x;
}
template<typename _T>
size_t BinTree<_T>::remove(_BinNodePtr _x)
{
if (!_x->_parent)
{
_x = _root = nullptr; size_t _n = _size; _size = 0; return _n;
}
else
{
(_x->_parent->_lc == _x) ? _x->_parent->_lc = nullptr : _x->_parent->_rc = nullptr;
_updateHeightAbove(_x->_parent);
size_t _n = removeAt(_x); _size -= _n; return _n;
}
}
template <typename _T>
size_t BinTree<_T>::removeAt(_BinNodePtr _x)
{
if (!_x) return 0;
size_t _n = 1 + removeAt(_x->_lc) + removeAt(_x->_rc);
_x = nullptr; return _n;
}
}
#endif
#include<iostream>
#include "BinTree.h"
using namespace std;
using namespace Shawn;
void print(int i)
{
cout << i << " ";
}
int main()
{
vector<int> pre{ 1, 2, 4, 7, 3, 5, 6, 8 }, in{ 4, 7, 2, 1, 5, 3, 8, 6 }, post{ 7, 4, 2, 5, 8, 6, 3, 1 };
size_t n = 8;
BinNode<int>* root1 = reconstruction_pre_in(n, pre, in);
BinNode<int>* root2 = reconstruction_post_in(n, post, in);
root1->travLevel(print);
cout << endl;
root2->travLevel(print);
cout << endl;
system("pause");
}