线索二叉树

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;
	}
	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>()){}
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 InsertLeft(ThreadNode<Type> *left);
	void InsertRight(ThreadNode<Type> *right);
	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> *pmove=m_pcurrent->m_pright;
	if(0==m_pcurrent->m_nrightthread){
		while(0==pmove->m_nleftthread){
			pmove=pmove->m_pleft;
		}
	}
	m_pcurrent=pmove;
	if(m_pcurrent==m_ptree.m_proot){
		return NULL;
	}
	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>::InsertLeft(ThreadNode<Type> *left){
	left->m_pleft=m_pcurrent->m_pleft;
	left->m_nleftthread=m_pcurrent->m_nleftthread;
	left->m_pright=m_pcurrent;
	left->m_nrightthread=1;
	m_pcurrent->m_pleft=left;
	m_pcurrent->m_nleftthread=0;
	if(0==left->m_nleftthread){
		m_pcurrent=left->m_pleft;
		ThreadNode<Type> *temp=First();
		temp->m_pright=left;
	}
	m_pcurrent=left;
}

template<typename Type> void ThreadInorderIterator<Type>::InsertRight(ThreadNode<Type> *right){
	right->m_pright=m_pcurrent->m_pright;
	right->m_nrightthread=m_pcurrent->m_nrightthread;
	right->m_pleft=m_pcurrent;
	right->m_nleftthread=1;
	m_pcurrent->m_pright=right;
	m_pcurrent->m_nrightthread=0;
	if(0==right->m_nrightthread){
		m_pcurrent=right->m_pright;
		ThreadNode<Type> *temp=First();
		temp->m_pleft=right;
	}
	m_pcurrent=right;
}

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(){
	Print(m_ptree.m_proot->m_pleft);
}
test.cpp

 

 

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;){
		threadtree.InsertLeft(new ThreadNode<int>(init[i++]));
		threadtree.InsertRight(new ThreadNode<int>(init[i++]));
	}
	threadtree.Print();
	cout<<endl<<endl;

	threadtree.InOrder();
	return 0;
}
时间: 2024-11-02 00:38:01

线索二叉树的相关文章

PHP实现二叉树/线索二叉树

PHP实现二叉树.线索二叉树,如下代码: <?php      require 'biTree.php';        $str = 'ko#be8#tr####acy#####';           $tree = new BiTree($str);      $tree->createThreadTree();        echo $tree->threadList() . "\n";从第一个结点开始遍历线索二叉树      echo $tree->

C#线索二叉树

using System; namespace BiThrTree{ /// <summary> /// 定义结点类: /// </summary> class BTNode { public char data; public int ltag,rtag;//0表示线索,1表示结点 public BTNode lchild,rchild; } class BiThrTree { /// <summary> /// 建立一棵新二叉树: /// </summary&

大话数据结构十五:线索二叉树

1. 什么是线索二叉树? n个结点的二叉链表中含有(2n-(n-1)=n+1个空指针域.利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前驱和后继结点的指针 (这种附加的指针称为"线索").这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树. 2. 为什么要加线索? ① 很多空指针域没有存储任何事物,对内存资源是一种浪费. ② 二叉链表中,我们只能知道每个结点指向其左右孩子结点的地址,却不知道每个结点的前驱是谁,后继是谁. ③ 线索链表解决了无法直接找到该结点在某

数据结构的C++实现之线索二叉树

我们知道满二叉树只是一种特殊的二叉树,大部分二叉树的结点都是不完全存在左右孩子的,即很多指针域没有被充分 地利用.另一方面我们在对一棵二叉树做某种次序遍历的时候,得到一串字符序列,遍历过后,我们可以知道结点之间的前 驱后继关系,也就是说,我们可以很清楚地知道任意一个结点,它的前驱和后继是哪一个.可是这是建立在已经遍历过的基 础之上的.在二叉链表上,我们只能知道每个结点指向其左右孩子结点的地址,而不知道某个结点的前驱是谁,后继是谁. 要想知道,必须遍历一次.以后每次需要知道时,都必须遍历一次.为什

算法速成(十二)树操作之线索二叉树

先前说了树的基本操作,我们采用的是二叉链表来保存树形结构,当然二叉有二叉的困扰之处,比 如我想找到当前结点 的"前驱"和"后继",那么我们就必须要遍历一下树,然后才能定位到 该"节点"的"前驱"和"后继",每次定位都是O(n),这 不是我们想看到的,那么有什么 办法来解决呢? (1) 在节点域中增加二个指针域,分别保存"前驱"和"后继",那么就 是四叉链表了,哈哈,还

在练习1中你已经定义了一个双向链表,请用它构造一个线索二叉树

问题描述 在练习1中你已经定义了一个双向链表,请用它构造一个线索二叉树 在练习1中你已经定义了一个双向链表,请用它构造一个线索二叉树 解决方案 http://blog.chinaunix.net/uid-26548237-id-3476920.html 解决方案二: 将排序二叉树转换成双向链表 解决方案三: 将一个二叉树转化为双向链表,不开辟新空间

关于线索二叉树的问题

问题描述 关于线索二叉树的问题 我想要进行线索二叉树的中序遍历,为什么我的这个程序编译通过却无法运行? //binthr.h template class binthrnode { public: binthrnode() //创建一个空结点 { lchild=rchild=NULL; } binthrnode(T e) { data=e; lchild=rchild=NULL; } binthrnode<T> *makebthrtree(binthrnode *bt); //生成二叉链表 v

PHP实现的线索二叉树及二叉树遍历方法详解_php技巧

本文实例讲述了PHP实现的线索二叉树及二叉树遍历方法.分享给大家供大家参考,具体如下: <?php require 'biTree.php'; $str = 'ko#be8#tr####acy#####'; $tree = new BiTree($str); $tree->createThreadTree(); echo $tree->threadList() . "\n";从第一个结点开始遍历线索二叉树 echo $tree->threadListReserv

线索二叉树的线索话和前序遍历,使用C++的实现,数据结构大试题,谢谢

问题描述 线索二叉树的线索话和前序遍历,使用C++的实现,数据结构大试题,谢谢 线索二叉树的线索话和前序遍历,使用C++的实现,数据结构大试题,谢谢 解决方案 http://blog.csdn.net/shifuwawa/article/details/4647727 解决方案二: http://blog.csdn.net/algorithm_only/article/details/6991254

后序线索二叉树怎么画 求图

问题描述 后序线索二叉树怎么画 求图 已知 后序遍历为 FDBGHECA 先序遍历 为 ABDFCEGH 中序为 BFDAGEHC 求画图 解决方案 http://zhidao.baidu.com/link?url=74xvMvCr9ceQUhJ-i43oDFWEGjnewmWmr-zpSfIymX_LFz_J0SI2tMgG4oZunGcOTOQij8edvcr3wEnXRgJUKLdR16cM3tmYa_iVSSM1ZqS