二叉树的线索化算法思想详解

    二叉树的线索化,这几天以来我很难掌握,今天终于想通了,哈哈,首先咱们来看看二叉树线索化以后会变成什么样子,这里咱们以图中的二叉树为例,图以下:
c++

wKioL1clqWXAc9hmAAAeyeZzebo767.png

    画的太糙,各位看官讲究着看吧- -。所谓二叉树的线索化,就是当一个节点的左右指针为空时,就让它的左右指针指向该节点的前驱或者后继(通常来讲左指针指向前驱,右指针指向后继)。这里不论指向前驱或者后继,咱们都应该线索化时,至少要明确两个节点指针的值,当前节点和当前节点的前驱/后继。这也是线索化的两种思路:
数据结构

    保存前驱:访问当前节点时若当前节点的左指针为空,则令左指针指向前驱,若前驱的右指针为空,则令前驱的右指针指向当前节点,代码描述以下:
ide

void visit(NODE* cur,NODE* &prev)//当前指针的前驱在当前指针访问时会改变,故传引用用来改变//prev
{
       if(prev->right==NULL;
           prev->right=cur;
       if(cur->left==NULL)
           cur->left=prev;
       prev=cur;
}

    这里咱们要注意的是应该先进行访问,最后再改变prev的值。
3d

    保存后继:这种方法很难作到,而且我的以为没有什么意义,由于在遍历整个数的过程当中咱们始终都会访问到一个节点的后继,若将要访问后继那咱们如何保存到将来的东西,即便经过相似栈的数据结构经过压栈来强行访问,效率也是不高的,在此不推荐。
指针

    接下来献上c++完整的线索二叉树结构以及中序线索化过程,经过递归与非递归两种方式实现,其余的都大同小异。
blog

    节点类定义以下:
递归

    

typedef char Datatype;
enum NodeType
{
	LINK,
	THERAD
};

struct TheardBinaryTreeNode
{
	TheardBinaryTreeNode* _left;
	TheardBinaryTreeNode* _right;
	NodeType _leftTag;
	NodeType _rightTag;
	Datatype _data;
	TheardBinaryTreeNode(const Datatype & data)
		:_left(NULL)
		, _right(NULL)
		, _leftTag(LINK)
		, _rightTag(LINK)
		,_data(data)
	{}
	TheardBinaryTreeNode()
		: _left(NULL)
		, _right(NULL)
		, _leftTag(LINK)
		, _rightTag(LINK)
		,_data((Datatype)0)
	{}
};

    中序线索化以下:
get

	void InTherad()
	{
		NODE* prev = NULL;
		_InTherad(_root, prev);
		//stack<NODE*>s;//借助栈来实现非递归的中序线索化
		//NODE* cur = _root;
		//NODE* prev = NULL;
		//while (!s.empty()||cur)
		//{
		//	while (cur)
		//	{
		//		s.push(cur);
		//		cur = cur->_left;
		//	}
		//	NODE* top = s.top();
		//	s.pop();
		//	if (top->_left == NULL&&top->_leftTag == LINK)
		//	{
		//		top->_left = prev;
		//		top->_leftTag = THERAD;
		//	}
		//	prev = top;
		//	if (top->_right == NULL&&top->_rightTag==LINK)
		//	{
		//		top->_rightTag = THERAD;
		//		if (!s.empty())
		//			top->_right = s.top();
		//	}
		//	else
		//		cur = top->_right;
		//}
	}
		void _InTherad(NODE*root, NODE* &prev)//递归的中序线索化
	{
		if (root == NULL)
			return;
		_InTherad(root->_left, prev);
		if (prev&&prev->_rightTag == LINK&&prev->_right == NULL)
		{
			prev->_right = root;
			prev->_rightTag = THERAD;
		}
		if (root->_leftTag == LINK&&root->_left == NULL)
		{
			root->_leftTag = THERAD;
			root->_left = prev;
			prev = root;
		}
		_InTherad(root->_right,prev);
	}

    若有不足或者疑问但愿留言提出。3Q -3-。
it

相关文章
相关标签/搜索