线索二叉树的关键点及其难点在于线索树的建立,可以先建立树,然后根据中序遍历(也可以是其他遍历)建立线索树,也可以在插入节点时建立线索二叉树。后者时间复杂度较小,但是需要注意的地方比较多。具体见代码。
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;
}