二叉树线索化实现

二叉树线索化

         二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。用二叉树作为存储结构时,取到一个节点,只 能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。

为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息。



enum PointerTag {THREAD, LINK};


template

struct BinaryTreeNode_Thd

{     T _data ;                         // 数据  

   BinaryTreeNode_Thd* _left;   // 左孩子   

  BinaryTreeNode_Thd* _right;  // 右孩子    

PointerTag   _leftTag ;          // 左孩子线索标志    

PointerTag   _rightTag ;         // 右孩子线索标志

};



测试用例


int array [10] = {1, 2, 3, '#', '#', 4, '#' , '#', 5, 6};

int array[15] = {1,2,'#',3,'#','#',4,5,'#',6,'#',7,'#','#',8};


创建二叉树

二叉树线索化实现_第1张图片

Node* _CreateTree(T*a,size_t size,size_t &index,const T& invalid)
	{
		Node* root = NULL;
		if(index_left=_CreateTree(a,size,++index,invalid);
			root->_right=_CreateTree(a,size,++index,invalid);
			
		}
		return root;
	}


前序线索化

二叉树线索化实现_第2张图片

void _PrevOrderThreading(Node*cur,Node*& prev)//线索化遍历//可循环,遇到一个节点找前驱或后继
	{
		if(cur==NULL)
			return ;

			while(cur->_left == NULL)
			{
				cur->_leftTag = THREAD;
				cur->_left = prev;
			}
			while(prev&&prev->_right == NULL)
			{
				prev->_rightTag = THREAD;
				prev->_right = cur;
			}
		
			prev = cur;
			if(cur->_leftTag == LINK)
			{
				_PrevOrderThreading(cur->_left,prev);
			}
			if(cur->_rightTag == LINK)
			{
				_PrevOrderThreading(cur->_right,prev);
			}
		
	}

前序遍历

void _PrevOverThd(Node*cur)
	{
		if(cur==NULL)
			return ;

		
		while(cur)
		{
			while(cur->_leftTag == LINK)
			{
				cout<_data<<" ";
				cur = cur->_left;
			}
			cout<_data<<" ";
			cur = cur->_right;
		}
		cout<

中序线索化

二叉树线索化实现_第3张图片


void _InorderThreading(Node* root,Node*& prev)
	{
		
		if(root==NULL)
			return ;
		_InorderThreading(root->_left,prev);
		//左子树
		if(root->_left==NULL)
		{
			root->_leftTag = THREAD;
			root->_left = prev;
		}
		//上一个节点
		if(prev&&prev->_right==NULL)
		{
			prev->_rightTag = THREAD;
                }
       }

 
  

中序遍历

void _InOrderThd(Node*root)
	{
	   
	   if(cur==NULL)
			return ;
      
		while(cur)
		{
			//找最左节点
			if(cur&&cur->_leftTag==LINK)
			{
				cur = cur->_left;
			}
			cout<_data<<" ";
			while(cur->_rightTag==THREAD)
			{
				cur = cur->_right;
				cout<_data<<" ";
			}
			if(cur->_rightTag==LINK)

			cur = cur->_right;
		}
		cout<



后序线索化


二叉树线索化实现_第4张图片

void _PostorderThreading(Node* root,Node* &prev)  
    {  
        if(root==NULL)  
            return;  
        _PostorderThreading(root->_left,prev);  
        _PostorderThreading(root->_right,prev);  
        if(root->_left==NULL)  
        {  
            root->_leftTag=THREAD;  
            root->_left=prev;  
        }  
        if(prev&&prev->_right==NULL)  
        {  
            prev->_rightTag=THREAD;  
            prev->_right=root;  
        }  
        prev=root;  
    }  

详细代码实现

#include
#include
#include
using namespace std;
enum Tag
{ 
	LINK ,THREAD
};
template 
struct BinaryTreeThNode
{
	T _data;
	BinaryTreeThNode* _left;
	BinaryTreeThNode* _right;
	Tag _leftTag;
	Tag _rightTag;
	BinaryTreeThNode(const T& x)
		:_data(x)
		,_left(NULL)
		,_right(NULL)
		,_leftTag(LINK)
		,_rightTag(LINK)
	{}
};
template 
class BinaryTree
{
	typedef  BinaryTreeThNode Node;
public:
	BinaryTree()
		:_root(NULL)
	{}
	BinaryTree(T *a,size_t size,const T&invalid)
	{
		assert(a);
		size_t index=0;
		_root= _CreateTree(a,size,index,invalid);
	}
   void InorderThreading()
	{
		Node* prev=NULL;
	    _InorderThreading(_root,prev);
	}
	void InOrderThd()
	{
		 _InOrderThd(_root);
	}
  
	void PrevOrderThreading()
	{
		Node* prev = NULL;
	     _PrevOrderThreading(_root,prev);
	}
	void PrevOverThd()
	{
		_PrevOverThd(_root);
	}
	
	void PostorderThreading()
	{
		Node* prev = NULL;
	   return _PostorderThreading(_root,prev);
	}
	void PostorderThd()
	{
		_PostorderThd(_root);
	}
protected:
	Node* _CreateTree(T*a,size_t size,size_t &index,const T& invalid)
	{
		Node* root = NULL;
		if(index_left=_CreateTree(a,size,++index,invalid);
			root->_right=_CreateTree(a,size,++index,invalid);
			
		}
		return root;
	}

	void _PrevOrderThreading(Node*cur,Node*& prev)//线索化遍历//可循环,遇到一个节点找前驱或后继
	{
		if(cur==NULL)
			return ;

			while(cur->_left == NULL)
			{
				cur->_leftTag = THREAD;
				cur->_left = prev;
			}
			while(prev&&prev->_right == NULL)
			{
				prev->_rightTag = THREAD;
				prev->_right = cur;
			}
		
			prev = cur;
			if(cur->_leftTag == LINK)
			{
				_PrevOrderThreading(cur->_left,prev);
			}
			if(cur->_rightTag == LINK)
			{
				_PrevOrderThreading(cur->_right,prev);
			}
		
	}
	void _PrevOverThd(Node*cur)
	{
		if(cur==NULL)
			return ;

		
		while(cur)
		{
			while(cur->_leftTag == LINK)
			{
				cout<_data<<" ";
				cur = cur->_left;
			}
			cout<_data<<" ";
			cur = cur->_right;
		}
		cout<_left,prev);
		//左子树
		if(root->_left==NULL)
		{
			root->_leftTag = THREAD;
			root->_left = prev;
		}
		//上一个节点
		if(prev&&prev->_right==NULL)
		{
			prev->_rightTag = THREAD;
			prev->_right = root;
		}
		prev = root;

		_InorderThreading(root->_right,prev);
	}
	void _InOrderThd(Node*root)
	{
	   
	   if(cur==NULL)
			return ;
      
		while(cur)
		{
			//找最左节点
			if(cur&&cur->_leftTag==LINK)
			{
				cur = cur->_left;
			}
			cout<_data<<" ";
			while(cur->_rightTag==THREAD)
			{
				cur = cur->_right;
				cout<_data<<" ";
			}
			if(cur->_rightTag==LINK)

			cur = cur->_right;
		}
		cout<_left,prev);  
        _PostorderThreading(root->_right,prev);  
        if(root->_left==NULL)  
        {  
            root->_leftTag=THREAD;  
            root->_left=prev;  
        }  
        if(prev&&prev->_right==NULL)  
        {  
            prev->_rightTag=THREAD;  
            prev->_right=root;  
        }  
        prev=root;  
    }  

/*???*///void _PostorderThd(Node*root)//线索化遍历//可循环,遇到一个节点找前驱或后继
//	{
//		Node* cur =root;
//		while(cur)
//		{
//			while(cur&&cur->_leftTag == LINK)
//			{
//				cout<_data<<" ";
//				cur = cur->_left;
//			}
//			cout<_data<<" ";
//			cur = cur->_right;
//		}
//		cout< tree(array2,15,'#');
	/*tree.InorderThreading();
	tree.InOrderThd();*/
	/*tree.PrevOrderThreading();
	tree.PrevOverThd();*/
	/*tree.PostorderThreading();
	tree.PostorderThd();*/
}
int main()
{
	TestBinaryTreeTh();
	system("pause");
	return 0;
}




你可能感兴趣的:(数据结构,二叉树,线索化,前中后序遍历)