线索二叉树的关键点及其难点在于线索树的建立,可以先建立树,然后根据中序遍历(也可以是其他遍历)建立线索树,也可以在插入节点时建立线索二叉树。后者时间复杂度较小,但是需要注意的地方比较多。具体见代码。
ThreadNode.h文件
template<typename Type> class ThreadTree; template<typename Type> class ThreadInorderIterator; template<typename Type> class ThreadNode{ public: friend class ThreadTree<Type>; friend class ThreadInorderIterator<Type>; //每一个新建的节点的左右指针都指向自己 ThreadNode():m_nleftthread(1),m_nrightthread(1){ m_pleft=this; m_pright=this; } //带参的构造函数指针都指向NULL ThreadNode(const Type item):m_data(item),m_pleft(NULL),m_pright(NULL) ,m_nleftthread(0),m_nrightthread(0){} private: int m_nleftthread,m_nrightthread; ThreadNode<Type> *m_pleft,*m_pright; Type m_data; };
ThreadTree.h文件
#include "ThreadNode.h" template<typename Type> class ThreadInorderIterator; template<typename Type> class ThreadTree{ public: friend class ThreadInorderIterator<Type>; //构造的根节点的左右指针都指向自己 ThreadTree():m_proot(new ThreadNode<Type>()){} private: ThreadNode<Type> *m_proot; };
ThreadInorderIterator.h文件
#include "ThreadTree.h" template<typename Type> class ThreadInorderIterator{ public: ThreadInorderIterator(ThreadTree<Type> &tree):m_ptree(tree),m_pcurrent(tree.m_proot){ // InThread(m_ptree.m_proot->m_pleft,m_ptree.m_proot); } ThreadNode<Type> *First(); ThreadNode<Type> *Prior(); ThreadNode<Type> *Next(); void Print(); void Print(ThreadNode<Type> *start, int n=0); void InOrder(); void Insert(ThreadNode<Type> *Node); ThreadNode<Type> *GetParent(ThreadNode<Type> *current); private: ThreadTree<Type> &m_ptree; ThreadNode<Type> *m_pcurrent; void InThread(ThreadNode<Type> *current,ThreadNode<Type> *pre); }; //建立中序遍历索引 template<typename Type> void ThreadInorderIterator<Type>::InThread( ThreadNode<Type> *current, ThreadNode<Type> *pre){ if(current!=m_ptree.m_proot){ InThread(current->m_pleft,pre); if(current->m_pleft==NULL){ current->m_pleft=pre; current->m_nleftthread=1; } if(pre->m_pright==NULL){ pre->m_pright=current; pre->m_nrightthread=1; } pre=current; InThread(current->m_pright,pre); } } //找到第一个被遍历的节点 template<typename Type> ThreadNode<Type>* ThreadInorderIterator<Type>::First(){ while(m_pcurrent->m_nleftthread==0){ m_pcurrent=m_pcurrent->m_pleft; } return m_pcurrent; } template<typename Type> ThreadNode<Type>* ThreadInorderIterator<Type>::Prior(){ ThreadNode<Type> *pmove=m_pcurrent->m_pleft; if(0==m_pcurrent->m_nleftthread){ while(0==pmove->m_nrightthread){ pmove=pmove->m_pright; } } m_pcurrent=pmove; if(m_pcurrent==m_ptree.m_proot){ return NULL; } return m_pcurrent; } template<typename Type> ThreadNode<Type>* ThreadInorderIterator<Type>::Next() { ThreadNode<Type>*temp=m_pcurrent->m_pright; if(m_pcurrent->m_nrightthread==0) { while(temp->m_nleftthread==0) { temp=temp->m_pleft; } } if(m_pcurrent->m_pright==m_ptree.m_proot) return NULL; m_pcurrent=temp; return m_pcurrent; } template<typename Type> void ThreadInorderIterator<Type>::InOrder(){ ThreadNode<Type> *pmove=m_ptree.m_proot; while(pmove->m_pleft!=m_ptree.m_proot){ pmove=pmove->m_pleft; } m_pcurrent=pmove; cout<<"root"; while(pmove!=m_ptree.m_proot&&pmove){ cout<<"--->"<<pmove->m_data; pmove=this->Next(); } cout<<"--->end"; } template<typename Type> void ThreadInorderIterator<Type>::Insert(ThreadNode<Type> *Node) { if(m_ptree.m_proot->m_pleft==m_ptree.m_proot) { m_ptree.m_proot->m_pleft=Node; Node->m_nleftthread=Node->m_nrightthread=1; Node->m_pleft=Node->m_pright=m_ptree.m_proot; m_ptree.m_proot->m_nleftthread=0; return ; } ThreadNode<Type>*temp=m_ptree.m_proot->m_pleft; while(1) { if(temp->m_data>Node->m_data) { if(temp->m_nleftthread==1) { Node->m_nleftthread=Node->m_nrightthread=1; temp->m_nleftthread=0; Node->m_pleft=temp->m_pleft; temp->m_pleft=Node; Node->m_pright=temp; return ; } temp=temp->m_pleft; } else if(temp->m_data<Node->m_data) { if(temp->m_nrightthread==1) { Node->m_nleftthread=Node->m_nrightthread=1; Node->m_pright=temp->m_pright; Node->m_nrightthread=1; temp->m_nrightthread=0; temp->m_pright=Node; Node->m_pleft=temp; temp->m_nleftthread=1; return ; } temp=temp->m_pright; } else { cout<<"this node have exit!"<<endl; return ; } } } template<typename Type> ThreadNode<Type>* ThreadInorderIterator<Type>::GetParent( ThreadNode<Type> *current){ ThreadNode<Type> *pmove=current; while(0==pmove->m_nleftthread){ pmove=pmove->m_pleft; } pmove=pmove->m_pleft; if(pmove==m_ptree.m_proot){ if(pmove->m_pleft==current){ return NULL; } } if(pmove->m_pright==current){ return pmove; } pmove=pmove->m_pright; while(pmove->m_pleft!=current){ pmove=pmove->m_pleft; } return pmove; } template<typename Type> void ThreadInorderIterator<Type>::Print(ThreadNode<Type> *start, int n){ if(start->m_nleftthread&&start->m_nrightthread){ for(int i=0;i<n;i++){ cout<<" "; } if(n>=0){ cout<<start->m_data<<"--->"<<endl; } return; } if(start->m_nrightthread==0){ Print(start->m_pright,n+1); } for(int i=0;i<n;i++){ cout<<" "; } if(n>=0){ cout<<start->m_data<<"--->"<<endl; } if(start->m_nleftthread==0){ Print(start->m_pleft,n+1); } } template<typename Type> void ThreadInorderIterator<Type>::Print(){ this->InOrder(); }
test.cpp文件
#include <iostream> using namespace std; #include "ThreadInorderIterator.h" int main(){ ThreadTree<int> tree; ThreadInorderIterator<int> threadtree(tree); int init[10]={3,6,0,2,8,4,9,1,5,7}; for(int i=0;i<10;i++){ threadtree.Insert(new ThreadNode<int>(init[i])); cout<<i<<endl; } threadtree.InOrder(); return 0; }