ThreadTree.h文件
#include<iostream>
using namespace std;
//殷书线索二叉树
//-----------------------------------------
//线索二叉树节点定义
template<typename T>
struct ThreadNode{
int ltag,rtag;
ThreadNode<T> *leftChild,*rightChild;
T data;
ThreadNode(const T item):data(item), leftChild(NULL),rightChild(NULL),ltag(0),rtag(0){}
};
//实现
template<typename T>
class ThreadTree{
public:
//普通构造函数
ThreadTree():root(NULL){}
//指定结束标志RefValue的构造函数
ThreadTree(T value):RefValue(value),root(NULL){}
//创建树
void CreateTree(){CreateTree(root);}
//中序遍历对创建好的普通二叉树进行中序线索化
void CreateInThread(){
ThreadNode<T> *pre = NULL; //第一个结点的左子树置为NULL
if (root != NULL) {
createInThread(root, pre);
//处理中序遍历的最后一个结点,最后一个结点的右子树置为空
pre->rightChild = NULL;
pre->rtag = 1;
}
}
//中序线索二叉树上三种遍历算法
void InOrder(){ InOrder(root);}
void PreOrder(){ PreOrder(root);}
void PostOrder(){ PostOrder(root);}
private:
//使用前序遍历创建二叉树(未线索化)
void CreateTree(ThreadNode<T>* &subTree){
//私有函数,建立二叉树
T item;
if(cin>>item){
if(item!=RefValue){
subTree=new ThreadNode<T>(item);
if(subTree==NULL){
cerr<<"存储分配错!"<<endl;exit(1);
}
CreateTree(subTree->leftChild);
CreateTree(subTree->rightChild);
}
else subTree=NULL;
}
}
//中序遍历对二叉树进行线索化
void createInThread(ThreadNode<T>*current,ThreadNode<T>* &pre){
if(current==NULL){
return;
}
createInThread(current->leftChild,pre); //递归左子树线索化
if(current->leftChild==NULL){ //建立当前节点的前驱节点
current->leftChild=pre;
current->ltag=1;
}
if(pre!=NULL&&pre->rightChild==NULL){
pre->rightChild=current;
pre->rtag=1;
}
pre=current; //用前驱记住当前节点
createInThread(current->rightChild,pre); //递归右子树线索化
}
//寻找根的下第 一个节点
ThreadNode<T>* First(ThreadNode<T>* current){
ThreadNode<T> *p=current;
while(p->ltag==0){
p=p->leftChild;
}
return p;
}
//寻找中序遍历下的后继节点
ThreadNode<T>* Next(ThreadNode<T>* current){
ThreadNode<T> *p=current->rightChild;
if(current->rtag==0){
return First(p);
}
else{
return p;
}
}
//寻找中序下最后一个结点
ThreadNode<T> * Last(ThreadNode<T> *current){
ThreadNode<T> *p=current;
while(p->rtag==0){
p=p->rightChild;
}
return p;
}
//寻找结点在中序下的前驱结点
ThreadNode<T>* Prior(ThreadNode<T>* current){
ThreadNode<T> *p=current->leftChild;
if(current->ltag==0){
return Last(p);
}
else{
return p;
}
}
//在中序线索化二叉树中求父节点
ThreadNode<T>* Parent(ThreadNode<T>* t){
ThreadNode<T>* p;
if(t==root) return NULL;
for(p=t;p->ltag==0;p=p->leftChild);
if(p->leftChild!=NULL){
for(p=p->leftChild;p!=NULL&&p->leftChild!=t&&p->rightChild!=t;p=p->rightChild);
}
if(p==NULL||p->leftChild==NULL){
for(p=t;p->rtag==0;p=p->rightChild);
for(p=p->rightChild;p!=NULL&&p->leftChild!=t&&p->rightChild!=t;p=p->leftChild);
}
return p;
}
//中序线索化二叉树上执行中序遍历的算法
void InOrder(ThreadNode<T>* p){
for(p=First(root);p!=NULL;p=Next(p)){
cout<<p->data<<" ";
}
cout<<endl;
}
//中序线索化二叉树上执行前序遍历的算法
void PreOrder(ThreadNode<T>* p){
while(p!=NULL){
cout<<p->data<<" "; //先访问根节点
if(p->ltag==0){
p=p->leftChild;
}
else if(p->rtag==0){
p=p->rightChild;
}
else{
while(p!=NULL&&p->rtag==1){
p=p->rightChild;
}
if(p!=NULL)
p=p->rightChild;
}
}
cout<<endl;
}
//中序线索二叉树的后序遍历算法
void PostOrder(ThreadNode<T>* p){
ThreadNode<T>* t=p;
while(t->ltag==0||t->rtag==0){
if(t->ltag==0) t=t->leftChild;
else if(t->rtag==0) t=t->rightChild;
}
cout<<t->data<<" ";
while((p=Parent(t))!=NULL){
if(p->rightChild==t||p->rtag==1)
t=p;
else{
t=p->rightChild;
while(t->ltag==0||t->rtag==0){
if(t->ltag==0) t=t->leftChild;
else if(t->rtag==0) t=t->rightChild;
}
}
cout<<t->data<<" ";
}
}
private:
//树的根节点
ThreadNode<T> *root;
T RefValue;
};
主函数main.cpp
#include<iostream>
#include"ThreadTree.h"
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(){
//abc##de#g##f###
ThreadTree<char> tree('#');
tree.CreateTree();
tree.CreateInThread();
tree.InOrder();
tree.PreOrder();
tree.PostOrder();
}