1. 程式人生 > >線索化二叉樹,前序中序後序遍歷(遞迴和非遞迴實現)

線索化二叉樹,前序中序後序遍歷(遞迴和非遞迴實現)

#include<iostream>
#include<string.h>
using namespace std;

enum PionerInfo
{
	LINK,THREAD
};

template<class T>
struct BinTreeNode
{
	BinTreeNode(const T& data)
	: _pLeft(NULL)
	, _pRight(NULL)
	, _pParent(NULL)
	, _data(data)
	, _leftThread(LINK)
	, _rightThread(LINK)
	{}
	BinTreeNode<T>* _pLeft;
	BinTreeNode<T>* _pRight;
	BinTreeNode<T>* _pParent;
	T _data;
	PionerInfo _leftThread;
	PionerInfo _rightThread;
};

template<class T>
class BinTree{
	typedef	BinTreeNode<T> Node;
	typedef Node* PNode;
public:
	BinTree()
		:_pRoot(NULL)
	{}
	BinTree(const T* array,size_t size,const T& invalid)
	{
		size_t index = 0;
		CreateBinTree(_pRoot,array, size, index, invalid);
	}
	void _PreOrder()
	{
		cout << endl;
		PreOrder(_pRoot);
	}
	void _InOrder()
	{
		InOrder(_pRoot);
		cout << endl;
	}
	void _EndOrder()
	{
		EndOrder(_pRoot);
		cout << endl;
	}
	void PreThread()
	{
		PNode prev = NULL;
		_PreThread(_pRoot,prev);
	}
	void InThread()
	{
		PNode prev = NULL;
		_InThread(_pRoot,prev);
	}
	void EndThread()
	{
		PNode prev = NULL;
		_EndThread(_pRoot, prev);
	}
	//非遞迴前序遍歷
	void PreOrder_Nor()
	{
		if (NULL == _pRoot)
			return;
		PNode pCur = _pRoot;
		while (pCur){
			while (pCur->_leftThread == LINK){
				cout << pCur->_data << " ";
				pCur = pCur->_pLeft;
			}
			cout << pCur->_data << " ";
			while (pCur->_rightThread == THREAD){
				pCur = pCur->_pRight;
				cout << pCur->_data << " ";
			}
			if (LINK == pCur->_leftThread)
				pCur = pCur->_pLeft;
			else
				pCur = pCur->_pRight;
		}
	}
	//非遞迴中序遍歷
	void InOrder_Nor()
	{
		if (NULL == _pRoot)
			return;
		PNode pCur = _pRoot;
		while (pCur){
			while (pCur->_leftThread == LINK){
				pCur = pCur->_pLeft;
			}
			cout << pCur->_data << " ";
			while (pCur->_rightThread == THREAD){
				pCur = pCur->_pRight;
				cout << pCur->_data << " ";
			}
				pCur = pCur->_pRight;
		}
	}
        //非遞迴後序遍歷
	void EndOrder_Nor()
	{
		if (_pRoot == NULL)
		   return;
		PNode pCur = _pRoot;
		while (pCur)
		{
			while (pCur && pCur->_rightThread == LINK){
				cout << pCur->_data << " ";
		        pCur = pCur->_pRight;
			}
			cout << pCur->_data << " ";
			while (pCur->_pLeft && pCur->_leftThread == THREAD)
			{
				pCur = pCur->_pLeft;
				cout << pCur->_data << " ";
			}
			pCur = pCur->_pLeft;
		}
	}
private:
	//根據前序的規則建立樹
	void CreateBinTree(PNode& pRoot, const T* array, size_t size, size_t& index, const T& invalid)
	{
		if (index < size&&array[index] != invalid){
			pRoot = new Node(array[index]);
			CreateBinTree(pRoot->_pLeft, array, size, ++index, invalid);
			if (pRoot->_pLeft)
				pRoot->_pLeft->_pParent = pRoot;
			CreateBinTree(pRoot->_pRight, array, size, ++index, invalid);
			if (pRoot->_pRight)
				pRoot->_pRight->_pParent = pRoot;
		}
	}
	void PreOrder(PNode pRoot)
	{
		if (pRoot){
			cout << pRoot->_data << " ";
			PreOrder(pRoot->_pLeft);
			PreOrder(pRoot->_pRight);
		}
	}
	void InOrder(PNode pRoot)
	{
		if (pRoot){
			InOrder(pRoot->_pLeft);
			cout << pRoot->_data << " ";
			InOrder(pRoot->_pRight);
		}
	}
	void EndOrder(PNode pRoot)
	{
		if (pRoot){
			EndOrder(pRoot->_pLeft);
			EndOrder(pRoot->_pRight);
			cout << pRoot->_data << " ";
		}
	}
	void _PreThread(PNode pRoot,PNode& prev)
	{
		if (pRoot){
			if (NULL == pRoot->_pLeft){
				pRoot->_pLeft = prev;
				pRoot->_leftThread = THREAD;
			}
			if (prev && NULL == prev->_pRight){
				prev->_pRight = pRoot;
				prev->_rightThread = THREAD;
			}
			prev = pRoot;
			if (LINK==pRoot->_leftThread)
				_PreThread(pRoot->_pLeft,prev);
			if (LINK==pRoot->_rightThread)
				_PreThread(pRoot->_pRight,prev);
		}
	}
	void _InThread(PNode pRoot, PNode& prev)
	{
		if (pRoot){
			_InThread(pRoot->_pLeft, prev);
			if (NULL == pRoot->_pLeft){
				pRoot->_pLeft = prev;
				pRoot->_leftThread = THREAD;
			}
			if (prev&&NULL == prev->_pRight){
				prev->_pRight = pRoot;
				prev->_rightThread = THREAD;
			}
			prev = pRoot;
			if (LINK == pRoot->_rightThread)
				_InThread(pRoot->_pRight, prev);
		}
	}
	void _EndThread(PNode pRoot, PNode& prev)
	{
		if (pRoot){
			_EndThread(pRoot->_pLeft, prev);
			if (LINK == pRoot->_rightThread)
				_EndThread(pRoot->_pRight, prev);
			if (NULL == pRoot->_pLeft){
				pRoot->_pLeft = prev;
				pRoot->_leftThread = THREAD;
			}
			if (prev&&NULL == prev->_pRight){
				prev->_pRight = pRoot;
				prev->_rightThread = THREAD;
			}
			prev = pRoot;
		}
	}
private:
	PNode _pRoot;
};


void test()
{
	char arr[] = "abd###ce##f";
	BinTree<char> bt(arr, strlen(arr), '#');
	//bt._PreOrder();
	//bt._InOrder();
	bt._EndOrder();
	//bt.PreThread();
	//bt.PreThread();
	//bt.PreOrder_Nor();
	/*bt.InThread();
	bt.InOrder_Nor();*/
	bt.EndThread();
	//bt.EndOrder_Nor();
	bt.EndOrder_Nor();

}

int main(){
	test();
	return 0;
}