二叉树的线索化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的线索化相关的知识,希望对你有一定的参考价值。

#include<iostream>
using namespace std;

enum PointerTag
{
                 THREAD,
                 LINK
};

template<class T>
struct BinaryTreeNodeThd
{

                BinaryTreeNodeThd( const T & x)
                                :_data( x)
                                ,_left( NULL)
                                ,_right( NULL)
                                ,_parent( NULL)
                                ,_leftTag( LINK)
                                ,_rightTag( LINK)
                {}

                 T _data;
                 BinaryTreeNodeThd<T >* _left;
                 BinaryTreeNodeThd<T >* _right;
                 BinaryTreeNodeThd<T >* _parent;
                 PointerTag _leftTag;           //左孩子线索标志
                 PointerTag _rightTag;          //右孩子线索标志
};
template<class T>
struct BinaryTreeThd
{
public:
                BinaryTreeThd< T>()
                                :_root( NULL)
                {}
                BinaryTreeThd< T>(const T* a,size_t size)
                {
                                 size_t index=0;
                                _root=_CreateTree( a,index,size );
                }
                 //中序线索化
                 void InOrderThreading()
                {
                                 BinaryTreeNodeThd<T >* prev=NULL;
                                _InOrderThreading(_root,prev);
                }
                 //前序线索化
                 void PreOrderThreading()
                {
                                 BinaryTreeNodeThd<T >* prev=NULL;
                                _PreOrderThreading(_root,prev);
                }
                 //后序线索化
                 void PostOrderThreading()
                {
                                 BinaryTreeNodeThd<T >* prev=NULL;
                                _PostOrderThreading(_root,prev);
                }
                 //中序线索化的遍历
                 void InOrderThd()
                {
                                 BinaryTreeNodeThd<T >* cur=_root;
                                 while(cur)
                                {
                                                 while(cur&&(cur->_leftTag!=THREAD ))   //找到最左节点
                                                {
                                                                cur=cur->_left;
                                                }
                                                cout<<cur->_data<< " ";    //输出最左节点

                                                 while(cur->_rightTag!=LINK )   //找后继节点
                                                {
                                                                cur=cur->_right;
                                                                cout<<cur->_data<< " ";
                                                }
                                                cur=cur->_right;
                                }
                                cout<<endl;
                }
                 //前序线索化的遍历
                 void PreOrderThd()
                {
                                 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 PostOrderThd()
                {
                                 if(_root==NULL )
                                                 return;
                                 if(_root->_left==NULL &&_root->_right==NULL)    //只有一个节点的情况
                                                cout<<_root->_data<<endl;
                                 else
                                {
                                 BinaryTreeNodeThd<T >* cur=_root->_left;
                                 BinaryTreeNodeThd<T >* prev=NULL;

                                 while(cur)
                                {

                                                 while(cur&&cur->_leftTag==LINK )
                                                                cur=cur->_left;

                                                 while(cur&&cur->_rightTag==THREAD )
                                                {
                                                                cout<<cur->_data<< " ";
                                                                prev=cur;
                                                                cur=cur->_right;
                                                }

                                                 if(cur==_root)
                                                {
                                                                cout<<_root->_data<< " ";
                                                                 break;
                                                }

                                                 while(cur&&cur->_rightTag==LINK &&cur->_right==prev)
                                                {
                                                                cout<<cur->_data<< " ";
                                                                prev=cur;
                                                                cur=cur->_parent;
                                                }

                                                 if(cur&&cur->_rightTag==LINK )
                                                                cur=cur->_right;
                                }
                                cout<<endl;
                                }
                }
                
protected:
                 BinaryTreeNodeThd<T >* _CreateTree(const T* a,size_t& index,size_t size)    //递归创建树
                {
                                 BinaryTreeNodeThd<T >* root=NULL;
                                 if((index <size)&&( a[index ]!=‘#‘))
                                {
                                                root= new BinaryTreeNodeThd <T>(a[index]);

                                                root->_left=_CreateTree( a,++index ,size);
                                                 if(root->_left)
                                                                root->_left->_parent=root;

                                                root->_right=_CreateTree( a,++index ,size);
                                                 if(root->_right)
                                                                root->_right->_parent=root;
                                }
                                 return 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 ;     //prev要动起来

                                _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 ;      //prev要动起来

                                 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 ->_left==NULL)
                                {
                                                 cur->_leftTag=THREAD ;
                                                 cur->_left=prev ;
                                }
                                 if(prev &&prev->_right== NULL)
                                {
                                                 prev->_rightTag=THREAD ;
                                                 prev->_right=cur ;
                                }

                                 prev=cur ;    //prev要动起来
                }
protected:
                 BinaryTreeNodeThd<T >* _root;
};
void test()
{
                 int array1[10]={1,2,3,‘#‘ ,‘#‘,4,‘#‘,‘#‘,5,6};
                 //int array1[1]={1};
                 BinaryTreeThd<int > btt1(array1,10);

                btt1.InOrderThreading();
                btt1.InOrderThd();       //3 2 4 1 6 5

                 /*btt1.PreOrderThreading();
                btt1.PreOrderThd();    */     //1 2 3 4 5 6

                 /*btt1.PostOrderThreading(); 
                btt1.PostOrderThd();  */       //3 4 2 6 5 1

                 int array2[15]={1,2,‘#‘ ,3,‘#‘,‘#‘,4,5, ‘#‘,6,‘#‘ ,7,‘#‘,‘#‘,8};
                 BinaryTreeThd<int > btt2(array2,15);

                btt2.InOrderThreading();
                btt2.InOrderThd();      //2 3 1 5 6 7 4 8

                 //btt2.PreOrderThreading();       //1 2 3 4 5 6 7 8
                 //btt2.PreOrderThd();

                 /*btt2.PostOrderThreading();
                btt2.PostOrderThd();  */      //3 2 7 6 5 8 4 1
}
int main()
{
                test();
                system( "pause");
                 return 0;
}


本文出自 “追寻内心的声音” 博客,转载请与作者联系!

以上是关于二叉树的线索化的主要内容,如果未能解决你的问题,请参考以下文章

线索化二叉树的相关操作

java实现线索化二叉树的前序中序后续的遍历(完整代码)

数据--第37课 - 线索化二叉树

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

数据结构二叉树

线索化二叉树