二叉树线索化实现

二叉树线索化

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

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



enum PointerTag {THREAD, LINK};


template <class T>

struct BinaryTreeNode_Thd

{     T _data ;                         // 数据  

   BinaryTreeNode_Thd<T >* _left;   // 左孩子   

  BinaryTreeNode_Thd<T >* _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};


创建二叉树

Node* _CreateTree(T*a,size_t size,size_t &index,const T& invalid)
	{
		Node* root = NULL;
		if(index<size && a[index] != invalid)
		{
			root =new Node(a[index]);
			root->_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<<cur->_data<<" ";
				cur = cur->_left;
			}
			cout<<cur->_data<<" ";
			cur = cur->_right;
		}
		cout<<endl;
	}

中序线索化


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;<pre class="html" name="code">                }
       }

 

中序遍历

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

			cur = cur->_right;
		}
		cout<<endl;
	}



后序线索化


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<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
enum Tag
{ 
	LINK ,THREAD
};
template <class T>
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 T>
class BinaryTree
{
	typedef  BinaryTreeThNode<T> 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<size && a[index] != invalid)
		{
			root =new Node(a[index]);
			root->_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<<cur->_data<<" ";
				cur = cur->_left;
			}
			cout<<cur->_data<<" ";
			cur = cur->_right;
		}
		cout<<endl;
	}
	
	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;
			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<<cur->_data<<" ";
			while(cur->_rightTag==THREAD)
			{
				cur = cur->_right;
				cout<<cur->_data<<" ";
			}
			if(cur->_rightTag==LINK)

			cur = cur->_right;
		}
		cout<<endl;
	}
	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;  
    }  

/*???*///void _PostorderThd(Node*root)//线索化遍历//可循环,遇到一个节点找前驱或后继
//	{
//		Node* cur =root;
//		while(cur)
//		{
//			while(cur&&cur->_leftTag == LINK)
//			{
//				cout<<cur->_data<<" ";
//				cur = cur->_left;
//			}
//			cout<<cur->_data<<" ";
//			cur = cur->_right;
//		}
//		cout<<endl;
//
//}
private:
	Node* _root;

};
void TestBinaryTreeTh()
{
	int array2[15] = { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 };
	BinaryTree<int> tree(array2,15,'#');
	/*tree.InorderThreading();
	tree.InOrderThd();*/
	/*tree.PrevOrderThreading();
	tree.PrevOverThd();*/
	/*tree.PostorderThreading();
	tree.PostorderThd();*/
}
int main()
{
	TestBinaryTreeTh();
	system("pause");
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值