殷书数据结构5.5——线索二叉树

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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值