线索thread二叉树
对于一个普通的二叉树

我们可以很明显的看到,在一个二叉树中,会有许多的空结点,而这些空结点必然会造成空间的浪费,为了解决这个问题,我们可以引入线索二叉树,把这些空结点利用起来,利用 ‘^’ 记录给定结点的前驱后继,那么问题就来了,该如何建立呢?
前面我们说过四种的遍厉方法,我应该用哪种方法来建立线索二叉树呢?
经过逐一的分析,我们发现利用中序遍历方法能够有效地建立起线索二叉树
我们先看一看在上述二叉树中中序遍历的结果
H D I B E A F C G
红色的结点为有空结点

在空结点中储存前驱与后继
单面对这样的一种二叉树时又怎么办呢?

中序遍历为
F D G B A C E
我们可以看到在b结点与结点 c出只有一个空结点
那机器该如何判断放的是线索还是指针呢?
为了解决这种问题,我们可以吧树的每个结点进行扩容

ltag : 为0时,表示lchild指向改结点的左孩子; 为1时,表示lchild指向该结点的前驱
rtag:为0时,表示rchild指向该结点的右孩子;为1时,表示rchild指向该结点的后继
线索二叉树的代码实现:
#include<iostream>
using namespace std; typedef char ElemType; //线索存储标志位
//Link 为0时,表示指向左右孩子的指针
//Thread 为1时,表示指向前驱后继的线索
typedef enum{Link, Thread} PointerTag; typedef struct BitThrNode
{
char data;
struct BitThrNode *lchild, *rchild;
PointerTag ltag;
PointerTag rtag;
}BitThrNode, *BitThrTree; //全局变量,指向刚刚访问过的节点
BitThrTree pre; //利用前序遍历创建二叉树
void createBitThrTree(BitThrTree *T) //根节点的地址
{
char c;
cin >> c;
if(c =='-')
{
*T=NULL;
}
else
{
*T=new BitThrNode;
(*T)->data=c;
(*T)->ltag=Link;
(*T)->rtag=Link;
createBitThrTree(&(*T)->lchild);
createBitThrTree(&(*T)->rchild);
}
} //中序遍历线索化
void InThreading(BitThrTree T)
{
if(T)
{
InThreading(T->lchild);//递归左孩子线索化
//结点处理
if(!T->lchild)
{
T->ltag=Thread;
T->lchild=pre;
} if(!pre->rchild)
{
pre->rtag=Thread;
pre->rchild=T;
} pre=T; InThreading(T->rchild);//递归右孩子线索化
}
} void InorderThreading(BitThrTree *p, BitThrTree T)
{
*p=new BitThrNode();
(*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 visit(char c)
{
cout<<c<<endl;
} //中序遍历二叉树非递归
void InorderTravel(BitThrTree T)
{
BitThrTree p;
p=T->lchild;
while(p!=T)
{
while(p->ltag==Link)
{
p=p->lchild;
}
visit(p->data); while(p->rtag==Thread&&p->rchild!=T)
{
p=p->rchild;
visit(p->data);
}
p=p->rchild;
}
} int main()
{
BitThrTree T=NULL;
BitThrTree p;
createBitThrTree(&T);
InorderThreading(&p,T); cout<<"中序遍历输出结果为"<<endl;
InorderTravel(p); return 0;
}
线索thread二叉树的更多相关文章
- 线索二叉树Threaded binary tree
摘要 按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列.在该序列中,除第一个结点外每个结点有且仅有一个直接前驱结点:除最后一个结点外每一个结点有且仅有一个直接后继结点.这 ...
- 树和二叉树->线索二叉树
文字描述 从二叉树的遍历可知,遍历二叉树的输出结果可看成一个线性队列,使得每个结点(除第一个和最后一个外)在这个线形队列中有且仅有一个前驱和一个后继.但是当采用二叉链表作为二叉树的存储结构时,只能得到 ...
- 线索二叉树的理解和实现(Java)
线索二叉树的基本概念 我们按某种方式对二叉树进行遍历,将二叉树中所有节点排序为一个线性序列,在该序列中,除第一个结点外每个结点有且仅有一个直接前驱结点:除最后一个结点外每一个结点有且仅有一个直接后继结 ...
- javascript实现数据结构:线索二叉树
遍历二叉树是按一定的规则将树中的结点排列成一个线性序列,即是对非线性结构的线性化操作.如何找到遍历过程中动态得到的每个结点的直接前驱和直接后继(第一个和最后一个除外)?如何保存这些信息? 设一棵二叉树 ...
- 算法与数据结构(三) 二叉树的遍历及其线索化(Swift版)
前面两篇博客介绍了线性表的顺序存储与链式存储以及对应的操作,并且还聊了栈与队列的相关内容.本篇博客我们就继续聊数据结构的相关东西,并且所涉及的相关Demo依然使用面向对象语言Swift来表示.本篇博客 ...
- Data Structure 之 二叉树
在计算机科学中,二叉树是每个节点最多有两个子树的树结构.通常子树被称作“左子树”(left subtree)和“右子树”(right subtree).二叉树常被用于实现二叉查找树和二叉堆 ...
- Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)——无非是在传统遍历过程中修改叶子结点加入后继结点信息(传统是stack记录),然后再删除恢复
先看看线索二叉树 n个结点的二叉链表中含有n+1(2n-(n-1)=n+1)个空指针域.利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索 ...
- 数据结构(C语言版)---二叉树
1.二叉树:任意一个结点的子结点个数最多两个,且子结点的位置不可更改,二叉树的子树有左右之分. 1)分类:(1)一般二叉树(2)满二叉树:在不增加树的层数的前提下,无法再多添加一个结点的二叉树就是满二 ...
- C#数据结构-线索化二叉树
为什么线索化二叉树? 对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上,否则我们只知道后续的左右子树.现在我们充分利用二叉树左右子树的空节点,分别指向当前节点的前驱.后继,便 ...
随机推荐
- 常见IT面试题
1.爬楼梯问题,有个N阶的楼梯,一个人可以一次爬1阶,也可以爬2阶,求问总计有多少种爬法? F(N)= F(N-1)+F(N-2). N=1时,有1种爬法,N=2时,有2种爬法.该题可以用递归方法求解 ...
- nginx https 配置
1.创建证书并下载(下载完成后有两个文件) *.pem *.key 2.将两个文件放在linux 某个目录下 3.配置nginx的conf配置文件 server{ # https 端口默认不是80,是 ...
- java自带的监控工具VisualVM一
转自:http://www.cnblogs.com/wade-xu/p/4369094.html 这篇总结的很不错(本人亲自操手学习),留着以后复习备用,很适合入门级的学习者: VisualVM 是一 ...
- 通过linux的iso镜像安装(RPM)扩展工具包
通过linux的iso镜像安装(RPM)扩展工具包 在linux安装软件时,现在越来越流行通过rpm指令安装完成,原因是:采用RPM安装简单方便:越来越多的软件提供RPM安装包:linux的IOS镜像 ...
- Java 序列化 序列化与单例模式 [ 转载 ]
Java 序列化 序列化与单例模式 [ 转载 ] @author Hollis 本文将通过实例+阅读Java源码的方式介绍序列化是如何破坏单例模式的,以及如何避免序列化对单例的破坏. 单例模式,是设计 ...
- C# 导出Word
导出word文档(无模版): using Microsoft.Office.Interop.Word; public static string CreateWordFile(CaseVM model ...
- String to Double出现误差
场景描述 做实际项目的时候,由于使用Double类的valueOf得到一个用String类型保存的金额参数(单位为元),当需要转换成以分为单位即整形表示(Integer类表示)时,需要用之前得到的do ...
- C#模板打印功能-模板为WPS或Excel
//---WPS----- using EtApp = ET; using System.Reflection; using System.Runtime.InteropServices; using ...
- php添加扩展插件
给PHP安装扩展的方式有好多 一.重新编译 进入PHP源码目录./configure --prefix=/usr/local/php ...[其他编译参数] 二.通过phpize添加扩展 进入PHP源 ...
- 【Python之路】第七篇--Python基础之面向对象及相关
面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查obj是否是类 cls 的对象 class Foo(objec ...