线索二叉树的结构实现

这个弄了好久,最主要理解中序遍历各节点的lchild指向左孩子还是前驱

和rchild指向右孩子还是后继,

还有线索化前的初始化和线索好之后的初始化(不知道这么说对不对,毕竟初学),

可以看看小甲鱼的视频,讲解的很不错,

上代码,前序输入就行,看代码自行了解输入规则,

#include<cstdio>
#include<cstring>
#include<cstdlib>

typedef enum {
	Link,Thread
}PointerTag;

typedef struct BiThrNode{
	char data;
	struct BiThrNode *lchild,*rchild;
	PointerTag LTag;
	PointerTag RTag;
}BiThrNode,*BiThrTree;

BiThrTree pre;
void CreateThrTree(BiThrTree *T){
	char c;
	scanf("%c",&c);
	if(‘ ‘ == c){
		(*T) = NULL;
	}else{
		*T = (BiThrTree)malloc(sizeof(BiThrNode));
		(*T)->data = c;
		(*T)->LTag = Link;
		(*T)->RTag = Link;
		CreateThrTree(&(*T)->lchild);
		CreateThrTree(&(*T)->rchild);
	}
}
void InThreading(BiThrTree T){
	if(T){
		InThreading(T->lchild);
		if(T->lchild == NULL){
			T->LTag = Thread;
			T->lchild = pre;
		}
		if(pre->rchild == NULL){
			pre->RTag = Thread;
			pre->rchild = T;
		}
		pre = T;
		InThreading(T->rchild);
	}
}
void InOrderThreading(BiThrTree *p,BiThrTree T){
	*p = (BiThrTree)malloc(sizeof(BiThrNode));
	(*p)->LTag = Link;
	(*p)->RTag = Thread;
	(*p)->rchild = *p;
	if(!T){
		(*p)->lchild = *p;
	}else{
		(*p)->lchild = T;
		pre = *p;

		InThreading(T);
		pre->rchild = *p;
		pre->RTag = Thread;
		(*p)->rchild = pre;
	}
}
void OnOrderTraverse(BiThrTree T){
	BiThrTree p;
	p = T->lchild;
	while(p != T){
		while(p->LTag == Link){
			p = p->lchild;
		}
		printf("%c\n",p->data);
		while(p->RTag == Thread && p->rchild != T){
			p = p->rchild;
			printf("%c\n",p->data);
		}
		p = p->rchild;
	}

}
int main(){
	BiThrTree p,T;

	CreateThrTree(&T);

	InOrderThreading(&p,T);

	OnOrderTraverse(p);
//	InThreading(T);
	return 0;
}

  

时间: 2024-11-14 13:14:43

线索二叉树的结构实现的相关文章

(原)数据结构——线索二叉树

原文地址:http://www.cnblogs.com/Security-Darren/p/4716082.html 转载务必注明出处! 线索二叉树的思想来源于二叉树的存储结构中,存在一些空的指针域,因此是否能够将这些空间利用起来,存储一些关于节点间先后顺序的信息,由此产生了线索二叉树.线索二叉树中,线索反映前驱.后继的关系,而指针则体现左右子树. 以二叉链表为例,线索二叉树存储结构上的特点是添加标识符,表明左右指针域究竟存的是指向前驱和后继的线索,还是指向左右子树的指针: 线索二叉树的优势是一

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉搜索树.红黑树.线索二叉树,它们在解决实际问题中有着非常重要的应用.本文主要从概念和一些基本操作上进行分类和总结. 一.概念总揽 (1) 堆 堆(heap order)是一种特殊的表,如果将它看做是一颗完全二叉树的层次序列,那么它具有如下的性质:每个节点的值都不大于其孩子的值,或每个节点的值都不小于其孩子的值

二叉树 二叉树的性质 存储结构 遍历二叉树 C实现二叉树的创建和遍历 线索二叉树

定义 二叉树(binary tree)是n(n>=0)个结点的有限集合,该集合为空集合称为空二叉树,或者有一个根结点和两棵互不相交的,分别称为树根结点的左孩子树和右孩子树组成. 二叉树的特点 每个结点最多有两棵子树,所以二叉树总没有度大于2的结点 左子树和右子树是有顺序的,次数不能任意颠倒 即使树中某结点只有一棵子树,也要区分是左子树还是右子树 特殊的二叉树 1. 斜树 所有的结点都只有左子树的二叉树称为左斜树; 所有的结点都只有右子树的二叉树称为右斜树; 这两者统称为斜树 2. 满二叉树 在一

二叉树之线索二叉树

相对于顺序存储结构而言,利用链式存储结构的二叉树已经有了很高的存储效率,单是还是有空间上未利用到的地方,比如说叶子结点的左右孩子是空的,指向左右孩子的指针就是空闲的,没有被利用到:而且,有时候给定一个结点,我们需要查找该结点的前驱结点和后继结点,如果按照中序遍历的做法去查找的话,对于一个非叶子结点,其前驱和后继结点查找可以以下算法: 1.preNode=node.left;//前去结点就是该结点的左孩子 2.subNode=search(node.right)://后继结点是该结点的右子树的最左

一步一步写数据结构(线索二叉树)

线索二叉树,在原始二叉树的基础上对节点进行“扩容”,使之变成了一颗节点信息更加丰富,利用率更高的二叉树.具体来说增加了两个指示标签,ltag和rtag,每个标签有两个值,1和0,0代表存在孩子,指针指向相应孩子,1代表没有对应的孩子,指针表示线索,指向其前驱或后继.这样虽然节点多占用了空间(其实很少,只是两个枚举常量而已),换来的却是让原来结构中存在的大量空指针利用起来,变成线索,指示前驱后继,从而使得空间利用效率大大提高, 并且有了线索以后,对后续的查找等操作提高很多效率. 下面是代码,本来以

线索二叉树的实现

<span style="font-size:18px;">/* 1.二叉树遍历算法提供了二叉树的一次性遍历,可是二叉树遍历算法无法实现用户程序像分步 遍历单链表那样分步遍历二叉树.线索二叉树就是专门为实现分步遍历二叉树而设计的.线索二叉树能够实现像双向 链表那样,既能够从前向后分步遍历二叉树,又能够从后向前分步遍历二叉树 2.当按某种规则遍历二叉树时,保存遍历时得到的节点的后继节点信息和前驱节点信息的最经常使用的方法是建立线索二叉树 3.线索二叉树的规定:当某节点的左指针

javascript实现数据结构:线索二叉树

遍历二叉树是按一定的规则将树中的结点排列成一个线性序列,即是对非线性结构的线性化操作.如何找到遍历过程中动态得到的每个结点的直接前驱和直接后继(第一个和最后一个除外)?如何保存这些信息? 设一棵二叉树有n个结点,则有n-1条边(指针连线) , 而n个结点共有2n个指针域(Lchild和Rchild) ,显然有n+1个空闲指针域未用.则可以利用这些空闲的指针域来存放结点的直接前驱和直接后继信息. 对结点的指针域做如下规定: 1.若结点有左子树,则其leftChild域指示其左孩子,否则令leftC

小堆 线索二叉树补充

1.小堆: 堆的构造,i>数组直接生成堆(向下调整),iii>插入创建堆(向上调整): (1).怎么实现一次调整? 找到最后一个非叶子结点,n/2-1:一直往下调整即可! (2)堆排----->优先级队列 堆的删除,只能是堆顶元素,再拿最后一个元素补充上去.在向下做一次调整.形成新的堆结构(满足堆的性质),将删除的数字输出就是堆排. 小堆:根(父)小于左右结点:最小的数字先出: 大堆:根(父)大于左右结点:最大的数字先出:   因而,进行堆排是就是优先级队列! 2.线索二叉树的查找父结点

线索二叉树

用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继.但是常常我们会想要更加直观的知道节点的前驱后继.线索二叉树显得尤为的重要.   线索二叉树的关键就是要定义一个全局变量来存放上一个访问过的结点.   Node* prev; (一)前序线索二叉树 void PrevOrderTag() { _PrevOrderTag(_root); } void _PrevOrderTag(Node* root)//前序线索二叉树 { if (roo