線索化二叉樹

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

enum PointerTag { THREAD, LINK };     //枚舉

前言:爲了遍歷的方便,我們在二叉樹中引入前驅和後序,這樣就儲存了相關信息。
其結構如下:

wKioL1cfXSLC_flJAAAUR9tbc5M285.png

template <class T>
struct BinaryTreeThdNode
{
	T _data;                         // 數據
	BinaryTreeThdNode<T >* _left;   // 左孩子
	BinaryTreeThdNode<T >* _right;  // 右孩子
	PointerTag   _leftTag;          // 左孩子線索標誌
	PointerTag   _rightTag;         // 右孩子線索標誌

	BinaryTreeThdNode(const T& x)
		:_left(NULL)
		, _right(NULL)
		, _leftTag(LINK)
		, _rightTag(LINK)
		, _data(x)
	{}
};

template<class T>
class BinaryTreeThd
{
	typedef BinaryTreeThdNode<T> Node;
public:
	BinaryTreeThd(int* a, size_t size, const T& invalid)
	{
		size_t index = 0;
		_root = _CreateTreeThd(a, size, invalid, index);
	}

	Node* _CreateTreeThd(int* a, size_t size, const T& invalid, size_t& index)
	{
		Node* root = NULL;
		if (index < size && a[index] != invalid)
		{
			root = new Node(a[index]);
			root->_left = _CreateTreeThd(a, size, invalid, ++index);
			root->_right = _CreateTreeThd(a, size, invalid, ++index);
		}

		return root;
	}

	//void PrevOrderThreading();   //前序
	//	void PostOrderThreading();   //後序
	void InOrderThreading()  //用遞歸實現中序線索化二叉樹
	{
		Node* prev = NULL;
		_InOrderThreading(_root, prev);
	}


	void InOrder()    //遞歸打印
	{
		_InOrder(_root);
		cout << endl;
	}

protected:
	void _InOrderThreading(Node* root, Node* prev)  //遞歸實現線索化二叉樹
	{
		if (root == NULL)
			return;

		if (root->_leftTag == LINK)
			_InOrderThreading(root->_left, prev);

		if (root->_left == NULL)
		{
			root->_left = prev;
			root->_leftTag = THREAD;
		}
		if (root->_right == NULL)
		{
			root->_rightTag = THREAD;
		}
		if (prev != NULL && prev->_rightTag == THREAD)
		{
			prev->_right = root;
		}

		prev = root;

		if (root->_rightTag == LINK)
			_InOrderThreading(root->_right, prev);
	}


	void InOrderThreading()      /*用棧線索化二叉樹*/
	{
		stack<Node*> s;
		Node* prev = NULL;
		Node* cur = _root;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}
			cur = s.top();
			s.pop();
			if (cur->_left == NULL)
			{
				cur->_left = prev;
				cur->_leftTag = THREAD;
			}
		prev = cur;
			if (cur->_right == NULL && !s.empty())
			{
				cur->_right = s.top();
				cur->_rightTag = THREAD;
				cur = NULL;
			}

			else
			{
				cur = cur->_right;
			}
		}
	}


	void _InOrder(Node* root)   //遞歸打印線索化二叉樹
	{
		if (root == NULL)
			return;
		if (root->_leftTag == LINK)
			_InOrder(root->_left);

		cout << root->_data << " ";
		if (root->_rightTag == LINK)
		{
			_InOrder(root->_right);
		}

	}


	void InOrder()      //用棧打印
	{
		if (_root == NULL)
			return;
		Node* cur = _root;
		while (cur)
		{
			while (cur->_left)
			{
				cur = cur->_left;
			}
			cut << cur->_data << " ";
			if (cur->_rightTag == THREAD)
			{
				cout << cur->_right->_data << " ";
				cur = cur->_right;
			}
			else if (cur->_right == LINK)
			{

			}
		}
	}


	void InOrderM()      //循環打印
	{
		Node* cur = _root;
		while (cur)
		{
			while (cur->_leftTag == LINK)
				cur = cur->_left;

			cout << cur->_data << " ";

			while (cur->_rightTag == THREAD)
			{
				cur = cur->_right;
				if (cur == NULL)
				{
					cout << endl;
					return;
				}
				cout << cur->_data << " ";
			} 

			cur = cur->_right;
		}

	}


	Node* _root;
};

void test()
{
	int a[] = { 1, 2, '#', 3, 4, 5, '#', 6 };

	BinaryTreeThd<int> b(a, 8, '#');
	b.InOrderThreading();
	b.InOrder();
}



int main()
{

	test();
	system("pause");
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章