/**************
http://anycodes.cn/zh/
http://blog.csdn.net/zdf0414/article/details/50083561
******************/
      #include<iostream>
using namespace std;
#include<stack>
#include <vector>  
enum PointTag
{
	LINK,
	THREAD,
};
struct BinTreeThingNode
{
	char _data;
	BinTreeThingNode*_left;
	BinTreeThingNode*_right;
	PointTag _leftTag;
	PointTag _rightTag;
	BinTreeThingNode(const char &data)
		:_data(data)
		, _left(NULL)
		, _right(NULL)
		, _leftTag(LINK)
		, _rightTag(LINK)
	{}
};
char s[]="123##4##56####";int i=0;
class BinTreeThreading
{
public:
	BinTreeThreading(const char *str)
	{
		_CreatBinTreeThreading(_root,str);//递归创建二叉树
	}
	
	void PostThread()//后序线索化
	{
		BinTreeThingNode*prev = NULL;
		_PostOderThread(_root, prev);
	}
	
	//后序线索化的遍历
	void PostSortwz()
	{
	    _PostSortwz(_root);
	}
	void PostSort()
	{
		BinTreeThingNode*cur = _root;
		BinTreeThingNode *lastvisited = NULL;
		  
		while (cur)
		{
			//一直寻找以cur为根节点的二叉树的最左边的叶子节点
			//cur->_left != lastvisited:当cur是通过其左孩子找到的时,不用又对cur进行重复找最左边的叶子节点
			while (cur&&cur->_leftTag != THREAD&& cur->_left != lastvisited)
			{
				cur = cur->_left;
			}
			if (cur && (cur->_rightTag == THREAD))//当cur无右孩子时,cur就可以被访问了
			{
				cout << cur->_data << " ";
				lastvisited = cur;
			}
			if (cur == _root&&cur->_right == NULL)//当根节点被访问时,遍历完成
			{
				cout << cur->_data << " ";
				return;
			}

			cur = cur->_right;


			//当cur的右孩子被访问过了,cur就可以被访问了。并且可知cur无后继,所以开始寻找cur的根节点
			while (cur && cur->_right == lastvisited)
			{
				cout << cur->_data << " ";
				lastvisited = cur;
				_Parent(_root, &cur); //寻找cur的根节点
				if (cur == lastvisited)
				{
					return;
				}
			}//while处理的情况是:当cur是通过其右孩子找到时
		}
	}
	
protected:
	//递归创建二叉树
	void _CreatBinTreeThreading(BinTreeThingNode*&root, const char *&str)
	{
		if (*str != '#'&&*str != '\0')
		{
			root = new BinTreeThingNode(*str);
			_CreatBinTreeThreading(root->_left, ++str);
			if (*str != '\0')
			{
				_CreatBinTreeThreading(root->_right, ++str);
			}
		}
	}
	//找当前节点的根节点
	void _Parent(BinTreeThingNode *&root,BinTreeThingNode **child)
	{
		BinTreeThingNode *tmp = *child;
		if (*child == root)
		{
			return;
		}
		if (root)
		{
			if (root->_left == *child || root->_right == *child)
			{
				*child = root;
				return;
			}
			if (root->_leftTag == LINK)
			{
				_Parent(root->_left, child);
			}
			if (tmp == *child&&root->_rightTag == LINK)
			{
				_Parent(root->_right, child);
			}
		}
	}
	
	//后序线索化的实现
	void _PostOderThread(BinTreeThingNode*&cur, BinTreeThingNode*&prev)
	{
		if (cur)
		{
			if (cur->_leftTag == LINK)
			{
				_PostOderThread(cur->_left, prev);
			}
			if (cur->_rightTag == LINK)
			{
				_PostOderThread(cur->_right, prev);
			}
			if (cur->_left == NULL)
			{
				cur->_leftTag = THREAD;
				cur->_left = prev;
			}
			if (prev&&prev->_right == NULL)
			{
				prev->_rightTag = THREAD;
				prev->_right = cur;
			}
			prev = cur;
		}
	}
	 void _PostSortwz(BinTreeThingNode*root)
	 {
	  stack<char>s;
	  BinTreeThingNode*cur=root;
	  while(cur)
	  {
	      s.push(cur->_data);//cout<<"("<<cur->_leftTag<<") ";
	      if(cur->_rightTag == 0)
	      cur=cur->_right;
	      else 
                  cur=cur->_left ;
              
	  }
 
	  char x;
	  while (! s.empty())  
      {  
       x= s.top();  
      cout<<x<<" ";
      s.pop();  
      }
	 }
private:
	BinTreeThingNode*_root;
};
int main()
{
    BinTreeThreading B(s);
     B.PostThread();
      B.PostSort(); cout<<endl;
       B.PostSortwz(); cout<<endl;
}
/*******  out put  ******* 
3 4 2 6 5 1 
3 4 2 6 5 1 

******************/