二叉樹的線索化算法思想詳解

    二叉樹的線索化,這幾天以來我很難掌握,今天終於想通了,哈哈,首先咱們來看看二叉樹線索化以後會變成什麼樣子,這裏咱們以圖中的二叉樹爲例,圖以下:
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

相關文章
相關標籤/搜索