#pragma once
#include <queue>
#include <stack>
#include <iostream>
#include <map>
template <typename T>
class BinaryTreeNode
{
public:
BinaryTreeNode() : m_pLeft(NULL), m_pRight(NULL), m_pParent(NULL){}
BinaryTreeNode(const T &data, BinaryTreeNode<T> *pLeft = NULL, BinaryTreeNode<T> *pRight = NULL, BinaryTreeNode<T> *pParent = NULL) : m_data(data), m_pLeft(NULL), m_pRight(NULL), m_pParent(pParent){}
const T& GetData() const {return m_data;}
void SetData(const T &data) {m_data = data;}
void SetLeft(BinaryTreeNode<T>* pLeft) {m_pLeft = pLeft;}
BinaryTreeNode<T>* GetLeft() const {return m_pLeft;}
void SetRight(BinaryTreeNode<T>* pRight) {m_pRight = pRight;}
BinaryTreeNode<T>* GetRight() const {return m_pRight;}
void SetParent(BinaryTreeNode<T>* pParent) {m_pParent = pParent;}
BinaryTreeNode<T>* GetParent() const {return m_pParent;}
private:
T m_data;
BinaryTreeNode<T> *m_pLeft;
BinaryTreeNode<T> *m_pRight;
BinaryTreeNode<T> *m_pParent;
};
template<typename T>
class BinaryTree
{
public:
BinaryTree(const T &data) : m_pRoot(new BinaryTreeNode<T>(data)){}
BinaryTree(BinaryTreeNode<T> *pRoot) : m_pRoot(pRoot){}
public:
BinaryTreeNode<T>* GetRoot() const {return m_pRoot;}
bool IsEmpty() const {return m_pRoot == NULL;}
void InsertLeft(BinaryTreeNode<T> *pCurrent, const T &data);
void InsertRight(BinaryTreeNode<T> *pCurrent, const T &data);
T GetNodeData(BinaryTreeNode<T> *pnode) const { return pnode->GetData(); }
void SetNodeData(BinaryTreeNode<T> *pnode, const T &data){pnode->SetData(data);}
BinaryTreeNode<T> * GetParent(BinaryTreeNode<T> *pnode){return pnode->GetParent();}
void LevelOrderTraverse(BinaryTreeNode<T> *proot) const;
void PerOrderTraverse(BinaryTreeNode<T> *proot) const;
void PerOrderTraverseStack(BinaryTreeNode<T> *proot) const;
void InOrderTraverse(BinaryTreeNode<T> *proot) const;
void InOrderTraverseStack(BinaryTreeNode<T> *proot) const;
void PostOrderTraverse(BinaryTreeNode<T> *proot) const;
void PostOrderTraverseStack(BinaryTreeNode<T> *proot) const;
private:
BinaryTreeNode<T> *m_pRoot;
};
template<typename T>
void BinaryTree<T>::InsertLeft(BinaryTreeNode<T> *pCurrent, const T &data)
{
BinaryTreeNode<T> *pnode = new BinaryTreeNode<T>(data);
pCurrent->SetLeft(pnode);
pnode->SetParent(pCurrent);
}
template<typename T>
void BinaryTree<T>::InsertRight(BinaryTreeNode<T> *pCurrent, const T &data)
{
BinaryTreeNode<T> *pnode = new BinaryTreeNode<T>(data);
pCurrent->SetRight(pnode);
pnode->SetParent(pCurrent);
}
template<typename T>
void BinaryTree<T>::LevelOrderTraverse(BinaryTreeNode<T> *proot) const
{
std::queue<BinaryTreeNode<T> *> que;
BinaryTreeNode<T> *pnode = NULL;
if(NULL != proot)
que.push(proot);
while(!que.empty())
{
pnode = que.front();
que.pop();
printf("%c \t", pnode->GetData());
if(pnode->GetLeft())
que.push(pnode->GetLeft());
if(pnode->GetRight())
que.push(pnode->GetRight());
}
}
template<typename T>
void BinaryTree<T>::PerOrderTraverse(BinaryTreeNode<T> *proot) const
{
if(proot)
{
std::cout << proot->GetData();
PerOrderTraverse(proot->GetLeft());
PerOrderTraverse(proot->GetRight());
}
}
template<typename T>
void BinaryTree<T>::PerOrderTraverseStack(BinaryTreeNode<T> *proot) const
{
BinaryTreeNode<T> *pnode = proot;
std::stack<BinaryTreeNode<T> *> stk;
while(!stk.empty() || pnode)
{
while(pnode)
{
stk.push(pnode);
std::cout << pnode->GetData();
pnode = pnode->GetLeft();
}
pnode = stk.top();
stk.pop();
pnode = pnode->GetRight();
}
}
template<typename T>
void BinaryTree<T>::InOrderTraverse(BinaryTreeNode<T> *proot) const
{
if(proot)
{
InOrderTraverse(proot->GetLeft());
std::cout << proot->GetData();
InOrderTraverse(proot->GetRight());
}
}
template<typename T>
void BinaryTree<T>::InOrderTraverseStack(BinaryTreeNode<T> *proot) const
{
std::stack<BinaryTreeNode<T> *> stk;
BinaryTreeNode<T> *pnode = proot;
while(!stk.empty() || pnode)
{
while(pnode)
{
stk.push(pnode);
pnode = pnode->GetLeft();
}
pnode = stk.top();
stk.pop();
std::cout << pnode->GetData();
pnode = pnode->GetRight();
}
}
template<typename T>
void BinaryTree<T>::PostOrderTraverse(BinaryTreeNode<T> *proot) const
{
if(proot)
{
PostOrderTraverse(proot->GetLeft());
PostOrderTraverse(proot->GetRight());
std::cout << proot->GetData();
}
}
template<typename T>
struct NodePair
{
BinaryTreeNode<T> * pnode;
int nTag; // 左右标志位
};
template<typename T>
void BinaryTree<T>::PostOrderTraverseStack(BinaryTreeNode<T> *proot) const
{
std::stack<NodePair<T>> stk;
BinaryTreeNode<T> *pnode = proot;
while(pnode || !stk.empty())
{
while(pnode)
{
NodePair<T> pair;
pair.pnode = pnode;
pair.nTag = 0;
stk.push(pair);
pnode = pnode->GetLeft();
}
while(!stk.empty() && stk.top().nTag == 1)
{
pnode = stk.top().pnode;
stk.pop();
std::cout << pnode->GetData();
}
// 遍历右子树
if(!stk.empty())
{
NodePair<T> pair = stk.top();
stk.pop();
pair.nTag = 1;
pnode = pair.pnode->GetRight();
stk.push(pair);
}
else
break;
}
}