#include <iostream>
#include <stack>
using namespace std;
template<class T>
class BinaryTree;
template<class T>
class BinaryTreeNode
{
friend BinaryTree<T>;
private:
BinaryTreeNode<T> *left;
BinaryTreeNode<T> *right;
public:
T data;
BinaryTreeNode(const T &item, BinaryTreeNode<T>*lptr = NULL, BinaryTreeNode<T>*rptr = NULL):data(item), left(lptr), right(rptr)
{
};
BinaryTreeNode<T>* GetLeft(){return left;}
BinaryTreeNode<T>*GetRight(){return right;}
void SetLeft(BinaryTreeNode<T>*L){left = L;}
void SetRight(BinaryTreeNode<T>*R){right = L;}
};
template<class T>
class BinaryTree
{
public:
BinaryTree() { root = NULL;};
~BinaryTree(){};
bool IsEmpty()const
{
return (root)?true:false;
}
bool Root(T&x) const
{
if(root)
{
x = root->data;
return true;
}
else
{
return false;
}
}
void MakeTree(const T & element, BinaryTree<T>&left, BinaryTree<T>&right)
{
root = new BinaryTreeNode<T>(element, left.root, right.root);
left.root = right.root = NULL;
}
void BreakTree(const T & element, BinaryTree<T>&left, BinaryTree<T>&right)
{
if (root == NULL)
{
return;
}
element = root->data;
left.root = root->GetLeft();
right.root = root->GetRight();
delete root;
root = NULL;
}
void Visit(const T& value)
{
return;
}
void PreOrderWithoutRecusion(BinaryTreeNode<T>*root)
{
using std::stack;
stack<BinaryTreeNode<T> *> astack;
BinaryTreeNode<T>* pointer = root;
while(!astack.empty() || pointer)
{
while(pointer)
{
Visit(pointer->data);
astack.push(pointer);
pointer = pointer->GetLeft();
}
if (!astack.empty())
{
pointer = astack.top();
astack.pop();
pointer = pointer->GetRight();
}
}
}
void InOrderWithoutRecusion(BinaryTreeNode<T>*root)
{
using std::stack;
stack<BinaryTreeNode<T> *> astack;
BinaryTreeNode<T>* pointer = root;
while(!astack.empty() || pointer)
{
while(pointer)
{
if (pointer->GetLeft() != NULL)
{
astack.push(pointer);
pointer = pointer->GetLeft();
}
}
if(!astack.empty())
{
pointer = astack.top();
Visit(pointer->data);
pointer = pointer->GetRight();
astack.pop();
}
}
}
enum Tags{ LEFT, RIGHT};
template<class T>
class StackElement
{
public:
BinaryTreeNode<T>*pointer;
Tags tag;
};
void PostOrderWithoutRecusion(BinaryTreeNode<T>*root)
{
using std::stack;
StackElement<T> element;
stack<StackElement<T> > astack;
BinaryTreeNode<T>*pointer;
if (NULL == root)
{
return;
}
else
{
pointer = root;
}
while(1)
{
while(pointer != NULL)
{
element.pointer = pointer;
element.tag = LEFT;
astack.push(element);
pointer = pointer->GetLeft();
}
if (!astack.empty())
{
element = astack.top();
astack.pop();
pointer = element.pointer;
if (element.tag == RIGHT)
{
Visit(pointer->data);
if (astack.empty())
{
return;
}
else
{
element = astack.top();
astack.pop();
pointer = element.pointer;
}
}
else
{
element.tag = RIGHT;
astack.push(element);
pointer = pointer->GetRight();
}
}
}
}
private:
BinaryTreeNode<T> *root;
};