template<class _T>
struct _TNode
{
_T data;
_TNode* pLeft;
_TNode* pRight;
_TNode* pParent;
_TNode()
{
pLeft = pRight = pParent = NULL;
}
};
template<typename _T>
class CBinaryTree
{
public:
CBinaryTree()
{
m_pRoot = NULL;
}
~CBinaryTree()
{
Clear();
}
void CreateTree(const _T& t);
void PreOrder() const;
void InOrder() const;
void PostOrder() const;
void LevelOrder() const;
void Layout() const;
void Layout2() const;
int Height() const;
private:
void CreateTree(_TNode<_T>** ppNode,const _T& t);
CBinaryTree(const CBinaryTree& tree);
CBinaryTree& operator = (const CBinaryTree& tree);
void Clear();
void Clear(_TNode<_T>* pNode);
int Height(const _TNode<_T>* pNode) const;
void inline Visit(const _TNode<_T>* PNode) const;
// 递归
void PreOrder(const _TNode<_T>* pNode) const;
void InOrder(const _TNode<_T>* pNode) const;
void PostOrder(const _TNode<_T>* pNode) const;
//非递归
void PreOrderNoRecursion(const _TNode<_T>* pNode) const;
void InOrderNoRecursion(const _TNode<_T>* pNode) const;
void PostOrderNoRecursion(const _TNode<_T>* pNode) const;
void LevelOrderNoRecursion(const _TNode<_T>* pNode) const;
_TNode<_T>* m_pRoot;
};
template<typename _T>
void CBinaryTree<_T>::Visit(const _TNode<_T>* pNode) const
{
if (pNode != NULL)
{
cout << pNode->data << endl;
}
}
template<typename _T>
void CBinaryTree<_T>::Clear(_TNode<_T>* pNode)
{
if (pNode != NULL)
{
_TNode<_T>* pLeft = pNode->pLeft;
_TNode<_T>* pRight = pNode->pRight;
delete pNode;
Clear(pLeft);
Clear(pRight);
}
}
template<typename _T>
void CBinaryTree<_T>::Clear()
{
stack<_TNode<_T>*,vector<_TNode<_T>*>> TStack;
if (m_pRoot != NULL)
TStack.push(m_pRoot);
_TNode<_T>* pCur = TStack.top();
while (!TStack.empty())
{
TStack.pop();
if (pCur != NULL)
{
TStack.push(pCur->pRight);
TStack.push(pCur->pLeft);
delete pCur;
pCur = NULL;
}
if (!TStack.empty())
{
pCur = TStack.top();
}
}
}
template<typename _T>
void CBinaryTree<_T>::CreateTree(const _T& t)
{
return CreateTree(&m_pRoot,t);
}
template<typename _T>
void CBinaryTree<_T>::CreateTree(_TNode<_T>** ppNode,const _T& t)
{
if (ppNode == NULL)
{
cout << "Invalid Parameter" << endl;
}
if (*ppNode == NULL)
{
*ppNode = new _TNode<_T>;
(*ppNode)->data = t;
}
else
{
if ((*ppNode)->data > t)
{
CreateTree(&(*ppNode)->pLeft,t);
}
else
{
CreateTree(&(*ppNode)->pRight,t);
}
}
}
template<typename _T>
void CBinaryTree<_T>::PreOrder() const
{
PreOrderNoRecursion(m_pRoot);
return PreOrder(m_pRoot);
}
template<typename _T>
void CBinaryTree<_T>::PreOrder(const _TNode<_T>* pNode) const
{
if (pNode == NULL)
return;
Visit(pNode);
PreOrder(pNode->pLeft);
PreOrder(pNode->pRight);
}
template<typename _T>
void CBinaryTree<_T>::PreOrderNoRecursion(const _TNode<_T>* pNode) const
{
stack<const _TNode<_T>*> TStack;
#if 0
if (pNode != NULL)
{
const _TNode<_T>* pCur = pNode;
while (pCur != NULL)
{
Visit(pCur);
if (pCur->pRight != NULL)
{
TStack.push(pCur->pRight);
}
if (pCur->pLeft != NULL)
{
TStack.push(pCur->pLeft);
}
if (!TStack.empty())
{
pCur = TStack.top();
TStack.pop();
}
else
{
pCur = NULL;
}
}
}
#else
const _TNode<_T>* pCur = pNode;
while (!TStack.empty() || (pCur != NULL))
{
while (pCur != NULL)
{
Visit(pCur);
TStack.push(pCur);
pCur = pCur->pLeft;
}
if (!TStack.empty())
{
pCur = TStack.top();
TStack.pop();
pCur = pCur->pRight;
}
}
#endif
}
template<typename _T>
void CBinaryTree<_T>::InOrder() const
{
InOrderNoRecursion(m_pRoot);
return InOrder(m_pRoot);
}
template<typename _T>
void CBinaryTree<_T>::InOrder(const _TNode<_T>* pNode) const
{
if (pNode == NULL)
return;
InOrder(pNode->pLeft);
Visit(pNode);
InOrder(pNode->pRight);
}
template<typename _T>
void CBinaryTree<_T>::InOrderNoRecursion(const _TNode<_T>* pNode) const
{
const _TNode<_T>* pCur = NULL;
stack<const _TNode<_T>*> TStack;
pCur = pNode;
while (!TStack.empty() || (pCur != NULL))
{
while (pCur != NULL)
{
TStack.push(pCur);
pCur = pCur->pLeft;
}
if (!TStack.empty())
{
pCur = TStack.top();
TStack.pop();
Visit(pCur);
pCur = pCur->pRight;
}
}
}
template<typename _T>
void CBinaryTree<_T>::PostOrder() const
{
PostOrderNoRecursion(m_pRoot);
return PostOrder(m_pRoot);
}
template<typename _T>
void CBinaryTree<_T>::PostOrder(const _TNode<_T>* pNode) const
{
if (pNode == NULL)
return;
PostOrder(pNode->pLeft);
PostOrder(pNode->pRight);
Visit(pNode);
}
template<typename _T>
void CBinaryTree<_T>::PostOrderNoRecursion(const _TNode<_T>* pNode) const
{
const _TNode<_T>* pCur = pNode;
const _TNode<_T>* pPre = NULL;
stack<const _TNode<_T>*> TStack;
while (!TStack.empty() || (pCur != NULL))
{
if (pCur != NULL)
{
TStack.push(pCur);
pCur = pCur->pLeft;
}
else
{
pCur = TStack.top();
if ((pCur->pRight != NULL) && (pPre != pCur->pRight))
{
pCur = pCur->pRight;
}
else
{
pPre = pCur;
Visit(pCur);
TStack.pop();
pCur = NULL;
}
}
}
}
template<typename _T>
void CBinaryTree<_T>::LevelOrder() const
{
return LevelOrderNoRecursion(m_pRoot);
}
template<typename _T>
void CBinaryTree<_T>::LevelOrderNoRecursion(const _TNode<_T>* pNode) const
{
queue<const _TNode<_T>*> TQueue;
const _TNode<_T>* pCur = pNode;
while (pCur != NULL)
{
Visit(pCur);
if (pCur->pLeft != NULL)
{
TQueue.push(pCur->pLeft);
}
if (pCur->pRight != NULL)
{
TQueue.push(pCur->pRight);
}
if (!TQueue.empty())
{
pCur = TQueue.front();
TQueue.pop();
}
else
{
pCur = NULL;
}
}
}
template<typename _T>
void CBinaryTree<_T>::Layout() const
{
stack<pair<const _TNode<_T>*,int>> TStack2;
stack<const _TNode<_T>*> TStack;
const _TNode<_T>* pCur = m_pRoot;
int index = 0;
while ( pCur != NULL || !TStack.empty())
{
while (pCur != NULL)
{
TStack.push(pCur);
TStack2.push(make_pair(pCur,index));
pCur = pCur->pLeft;
index++;
}
if (!TStack.empty())
{
pCur = TStack.top();
pair<const _TNode<_T>*,int> node = TStack2.top();
for (int i = 0; i < node.second; ++i)
{
cout << '/t' ;
}
cout << node.first->data << endl;
TStack.pop();
TStack2.pop();
pCur = pCur->pRight;
if (pCur == NULL)
index--;
}
}
}
template<typename _T>
void CBinaryTree<_T>::Layout2() const
{
queue<const _TNode<_T>*> TQueue;
queue<pair<const _TNode<_T>*,int>> TQueue2;
const _TNode<_T>* pCur = m_pRoot;
int index = 0;
while( pCur != NULL)
{
for (int i = 0; i < 12 - index; ++i)
cout << '/t';
cout << pCur->data << endl;
TQueue.push(pCur->pLeft);
TQueue.push(pCur->pRight);
++index;
pCur = TQueue.front();
TQueue.pop();
}
}
template<typename _T>
int CBinaryTree<_T>::Height() const
{
return Height(m_pRoot);
}
template<typename _T>
int CBinaryTree<_T>::Height(const _TNode<_T>* pNode) const
{
if (pNode == NULL)
return 0;
int left = 0;
int right = 0;
left = Height(pNode->pLeft);
right = Height(pNode->pRight);
return left>right?(left+1):(right+1);
}