线索化二叉树的非递归遍历(用前驱结点和后继访问)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线索化二叉树的非递归遍历(用前驱结点和后继访问)相关的知识,希望对你有一定的参考价值。

#pragma once
#include<iostream>
using namespace std;
enum PointTag
{
	THREAD,
	LINK
};
template<class T>
struct BinaryTreeNodeThd
{
	T _data;
	BinaryTreeNodeThd<T>* _left;
	BinaryTreeNodeThd<T>* _right;
	BinaryTreeNodeThd<T>* _parent;
	PointTag _leftTag;
	PointTag _rightTag;
	BinaryTreeNodeThd(const T& x)
		:_data(x)
		, _left(NULL)
		, _right(NULL)
		, _parent(NULL)
		, _leftTag(LINK)
		, _rightTag(LINK)
	{}
};
template<class T>
class BinaryTreeThd
{
protected:
	BinaryTreeNodeThd<T>* _CreateBinaryTree(T* a, size_t& index, const size_t size)
	{
		BinaryTreeNodeThd<T>* root = NULL;
		if (index < size&&a[index] != ‘#‘)
		{
			root = new BinaryTreeNodeThd<T>(a[index]);
			root->_left = _CreateBinaryTree(a, ++index, size);
			if (root->_left)
				root->_left->_parent = root;
			root->_right = _CreateBinaryTree(a, ++index, size);
			if (root->_right)
				root->_right->_parent = root;
		}
		return root;
	}
	void _Clear(BinaryTreeNodeThd<T>* root)
	{
		if (root)
		{
			if (root->_leftTag == LINK)
				_Clear(root->_left);
			if (root->_rightTag == LINK)
				_Clear(root->_right);
			delete root;
		}
	}
	void _InOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
	{
		if (cur == NULL)
			return;
		
		_InOrderThreading(cur->_left, prev);
		if (cur->_left==NULL)
		{
			cur->_leftTag = THREAD;
			cur->_left = prev;
		}
		if (prev&&prev->_right == NULL)
		{
			prev->_rightTag = THREAD;
			prev->_right = cur;
		}
		prev = cur;
		
		_InOrderThreading(cur->_right, prev);
	}
	
	void _PreOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
	{
		if (cur == NULL)
			return;
		
		if (cur->_left == NULL)
		{
			cur->_leftTag = THREAD;
			cur->_left = prev;
		}
		if (prev&&prev->_right == NULL)
		{
			prev->_rightTag = THREAD;
			prev->_right = cur;
		}
		prev = cur;
		if (cur->_leftTag == LINK)
			_PreOrderThreading(cur->_left, prev);
		if (cur->_rightTag == LINK)
			_PreOrderThreading(cur->_right, prev);
	}
	void _PostOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
	{
		if (cur == NULL)
			return;
		_PostOrderThreading(cur->_left, prev);
		_PostOrderThreading(cur->_right, prev);
		if (cur&&cur->_left == NULL)
		{
			cur->_leftTag = THREAD;
			cur->_left = prev;
		}
		if (prev&&prev->_right == NULL)
		{
			prev->_rightTag = THREAD;
			prev->_right = cur;
		}
		prev = cur;
	}
public:
	BinaryTreeThd()
		:_root(NULL)
	{}
	BinaryTreeThd(T* a,size_t size)
	{
		size_t index = 0;
		_root=_CreateBinaryTree(a, index, size);
	}
	~BinaryTreeThd()
	{
		_Clear(_root);
		_root = NULL;
	}
	void  PreOrderThreading()
	{
		BinaryTreeNodeThd<T>* prev = NULL;
		_PreOrderThreading(_root, prev);
	}
	/*void PreOrderThd()
	{
		if (_root == NULL)
			return;
		BinaryTreeNodeThd<T>* cur = _root;
		
		while (cur)
		{
			
			cout << cur->_data << " ";
			while (cur&&cur->_leftTag != THREAD)
			{
				cur = cur->_left;
				cout << cur->_data << " ";
			}
			
			while (cur&&cur->_rightTag != LINK)
			{
				cur = cur->_right;
				cout << cur->_data << " ";
			}
			if (cur->_leftTag == LINK)
				cur = cur->_left;
			else
				cur = cur->_right;
		}
		cout << endl;
	}*/
	//优化版前序遍历,发现规律,注意观察
	void PreOrderThd()
	{
		if (_root == NULL)
			return;
		BinaryTreeNodeThd<T>*cur = _root;
		while (cur)
		{
			while (cur&&cur->_leftTag == LINK)
			{
				cout << cur->_data << " ";
				cur = cur->_left;
			}
			cout << cur->_data << " ";
			cur = cur->_right;
		}
		cout << endl;
	}
	void  InOrderThreading()
	{
		BinaryTreeNodeThd<T>* prev = NULL;
		_InOrderThreading(_root, prev);
	}
	void InOrderThd()
	{
		if (_root == NULL)
			return;
		BinaryTreeNodeThd<T>* cur = _root;
		while (cur)
		{
			while (cur&&cur->_leftTag != THREAD)
				cur = cur->_left;
			cout << cur->_data << " ";
			while (cur&&cur->_rightTag != LINK)
			{
				cur = cur->_right;
				cout << cur->_data << " ";
			}
			cur = cur->_right;
		}
		cout << endl;
	}
	void PostOrderThreading()
	{
		BinaryTreeNodeThd<T>* prev = NULL;
		_PostOrderThreading(_root, prev);
	}
	//重点
	void PostOrderThd()
	{
		if (_root == NULL)
			return;
		BinaryTreeNodeThd<T>* cur = _root->_left;
		BinaryTreeNodeThd<T>* prev = NULL;
		int flag = 0;
		while (cur != _root)
		{
			while (cur&&cur->_leftTag == LINK)
			{
				cur = cur->_left;
			}
			while (cur&&cur->_rightTag == THREAD)
			{
				cout << cur->_data << " ";
				prev = cur;
				cur = cur->_right;
 			}
			if (_root == cur)
			{
				cout << _root->_data << " ";
				prev = _root;
				break;
			}
			while(cur&&_root!=cur&&cur->_rightTag == LINK&&cur->_right == prev)
			{
				cout << cur->_data << " ";
				prev = cur;
				cur = cur->_parent;
			}
			if (cur == _root)
			{
				if (flag == 0)
					flag = 1;
				else
					break;
			}
			if (cur&&cur->_rightTag == LINK&&cur != prev)
				cur = cur->_right;
			else
			{
				cout << cur->_data << " ";
				prev = cur;
				cur = cur->_parent;
			}
			
		}
		if(prev!=_root)
			cout << _root->_data << " ";
		cout << endl;
	}
protected:
	BinaryTreeNodeThd<T>* _root;
};
void  Test3()
{
        //注意测试用例
	//int array[18] = { 1, 2, 3, 7, ‘#‘,‘#‘,‘#‘,4,8,‘#‘,‘#‘,9,‘#‘,‘#‘,5,6,‘#‘,10};
	
	int array[10] = { 1, 2, 3, ‘#‘, ‘#‘, 4, ‘#‘, ‘#‘, 5, 6 };
	//int array[15] = { 1, 2, ‘#‘, 3, ‘#‘, ‘#‘, 4, 5, ‘#‘, 6, ‘#‘, 7, ‘#‘, ‘#‘, 8 };
	BinaryTreeThd<int> b2(array, 10);
	/*b2.InOrderThreading();
	b2.InOrderThd();*/
    /*b2.PreOrderThreading();
	b2.PreOrderThd();*/
	b2.PostOrderThreading();
	b2.PostOrderThd();
}
int main()
{
	Test3();
	system("pause");
	return 0;
}


本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1750536

以上是关于线索化二叉树的非递归遍历(用前驱结点和后继访问)的主要内容,如果未能解决你的问题,请参考以下文章

线索化二叉树

C++线索化二叉树

二叉树的线索化

二叉树的线索化

二叉树的线索化

C#数据结构-线索化二叉树