数据结构 —— 线索二叉树

2023-10-26

线索二叉树的意义

  • 对于一个有n个节点的二叉树,每个节点有指向左右孩子的指针域。其中会出现n+ 1个空指针域,这些空间不储存任何事物,浪费着内存的资源。
  • 对于一些需要频繁进行二叉树遍历操作的场合,二叉树的非递归遍历操作过程相对比较复杂,递归遍历虽然简单明了,但是会有额外的开销,对于操作的时间和空间都比较浪费。
  • 我们可以考虑利用这些空地址,存放指向节点在某种遍历次序下的前驱和后继节点的地址。通过这些前驱和后继节点的地址可以知道,从当前位置下一步应该走向哪里。

线索二叉树的定义

  • 指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树就称为线索二叉树。
  • 对二叉树以某种次序遍历使其变为线索二叉树的过程称为线索化。

线索二叉树结构的实现

二叉树的线索存储结构

为了区分二叉树某一节点是指向它的孩子节点还是指向前驱或者后继节点,我们可以在每个节点增设两个标志,Ltag,Rtag.
其中:

  • Ltag为0时,代表该节点指向它的左孩子,Ltag为1时,代表该节点指向它的前驱节点。
  • Rtag为0时,代表该节点指向它的右孩子,Rtag为1时,代表该节点指向它的后继节点。
    所以,线索二叉树结构定义代码如下:
typedef char BTDataType;

typedef enum{Link,Thread}PointerTag;//Link 是0,Thread 是1。

typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	PointerTag LTag ;
	PointerTag RTag;
	BTDataType data;
}BTNode;

二叉树的中序线索化

线索化的过程就是在遍历过程中修改空指针的过程
在这里插入图片描述
以上二叉树中序遍历可以得到:

  D B E A F C
  D的前驱是空,后继是B
  B的前驱是D,后继是E
  E的前驱是B,后继是A
  F的前驱是A,后继是C
  C的前驱是F,后继是空

线索化后:
在这里插入图片描述
中序遍历线索化的递归函数代码如下:

//中序线索化
BTNode* pre = NULL;/*全局变量,始终指向刚刚访问过的节点*/
void InThreading(BTNode* p)
{
	if (p == NULL) return;
	InThreading(p->left);//递归左子树线索化
	if (!p->left)//左孩子为空,left指针指向前驱
	{
		p->LTag = Thread;
		p->left = pre;
	}
	if (pre!=NULL && !pre->right)//右孩子为空,right指针指向后继指针。
	//这里判断 pre!=NULL 是因为线索化中序遍历的第一个节点(节点D)时,它并没有前驱节点,此时的pre仍然是NULL。
	{
		pre->RTag = Thread;
		pre->right = p;
	}
	pre = p;//保持pre指向p的前驱
	InThreading(p->right);
}

分析:

  1. if (!p->left)表示如果某节点的左指针域为空,因为其前驱节点刚刚访问过,并且赋值给了pre,所以可以将pre赋值给 l -> left,并且修改 p-> LTag = Thread,以完成前驱节点的线索化。
  2. pre 是 p 的前驱,那么, p 就是 pre 的后继。当pre -> right 为空时,就可以将p赋值给 pre -> right , 并且修改 pre -> RTag = Thread。

线索二叉树的中序遍历

void MidOrder(BTNode*p)
{
	while (p != NULL)
	{
		while (p->LTag == Link)//
		{
			p = p->left;
		}
		printf("%c ",p->data);
		while (p->RTag == Thread && p->right != p)
		{
			p = p->right;
			printf("%c ", p->data);
		}
		p = p->right;
	}
	return;
}

分析:

  1. while (T->ltag == Link)从根节点开始遍历,如果左标记是Link让它一直循环下去,
    直到找到标记为Thread的的结点,也就是要遍历的第一个结点,然后根据后驱指针找到后继结点
  2. 后面就是重复以上过程,直到遍历完整个二叉数。

总结

如果所用的二叉数需要经常遍历或查找结点时需要某种遍历序列中的前驱和后继,那么采用线索二叉数是一个很好的选择;

以上内容参考于《大话数据结构》。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构 —— 线索二叉树 的相关文章

随机推荐

  • LR(0)文法分析(通过例题穿插讲解)

    目录 LR 0 文法的字面含义 LR 0 分析表的构造 写在最后 LR 0 文法的字面含义 LR 0 分析法是其他LR分析法构造的基础 L表示从左往右扫描 R表示反向构造出一个最右推导 k表示向前看k个字符 缺省为1 在学习LR 0 分析时
  • Linux驱动框架与LED实战

    目录 驱动框架 相关文件 案例分析 LED驱动框架源码 led class c led class attrs leds class class结构体 led classdev register 某一类的设备创建 led classdev结
  • QT获取显示当前时间和日期

    获取当前时间和日期 QT中获取时间和日期的主要是 QTime QDate 和 QDateTime 这三个类 QTime 类 通过 QTime 类中提供的时间相关的方法 可以获取到当前系统时间 时 分 秒 毫秒 需要注意的是 计时的准确性由底
  • QWidget/QDialog主窗体设置边框圆角

    1 问题 QT中窗体QWidget和QDialog为容器 不能对窗体进行边框圆角样式改变 只能通过绘图QPainter 2 设置无上边框选项窗口 this gt setWindowFlags Qt Widget Qt FramelessWi
  • CSS学习笔记八——宽高自适应

    宽高自适应 一 宽度自适应 二 高度自适应 三 浮动元素的高度自适应 四 窗口自适应 五 结语 一 宽度自适应 不写宽度或者写 width auto就表示宽度自适应 可用于横栏或导航栏 与 width 100 不同 设为100 已经固定了宽
  • MySQL之无限级分类表设计

    首先查找一下goods cates表和table goods brands数据表 分别使用命令 root localhost test gt show columns from goods cates root localhost test
  • 【Spring源码】一:整体流程

    总流程 12 个方法 Prepare this context for refreshing prepareRefresh Tell the subclass to refresh the internal bean factory Con
  • 与焦虑同行,话技术领导者成长

    解码职场焦虑 系列直播第二期来啦 技术领导者在职场跃迁中 会因为各种内外因素的变化而产生焦虑 困惑 烦躁等情绪 我们该怎样与负面情绪共处 认识到局限 接纳并不完美的自己 从而稳步前行 技术Leader成长路上会面对哪些情绪挑战 高压和忙碌状
  • html提取信息变xml,网络爬虫笔记【7】 利用 XPATH 实现 XML 和 HTML 文本信息提取

    XML Extensible Markup Language 指可扩展标记语言 被设计用来传输和存储数据 HTML指的是超文本标记语言 Hyper Text Markup Language 是WWW上用于编写网页的主要工具 详细信息请参考
  • R语言做文本挖掘 Part3文本聚类

    Part3文本聚类 发现有人转载 决定把格式什么重新整理一遍 有时间做个进阶版文本挖掘 恩 原文地址 CSDN R语言做文本挖掘 Part3文本聚类 分类和聚类算法 都是数据挖掘中最常接触到的算法 分类聚类算法分别有很多种 可以看下下面两篇
  • 万字超详细的Java图书管理系统

    生命中的每个人都是一个故事 而每个故事都值得被讲述 作者 不能再留遗憾了 专栏 Java学习 该文章主要内容 用Java实现简单的图书管理系统 文章目录 前言 基本思路 书和书架 书Book类 书架BookList类 用户身份User 父类
  • Oracle : ORA-00001: unique constraint (SHULAN_TEST.SYS_C0026496) violated

    Caused by java lang IllegalStateException Can t overwrite cause with java sql SQLIntegrityConstraintViolationException O
  • Random Vectors and the Variance-Covariance Matrix

    Random Vectors and the Variance Covariance Matrix pdf 多维变量概率论 Definition 1 随机向量 x x 1
  • jsp与html,html与web语言的交互

    jsp 又名java Server Pages 用于开发动态网页 文件扩展名为jsp 优点 1 首先jsp是一种服务端技术 提供了动态接口 用于不断更改数据并调用服务器操作 2 jsp本身是一种编译好的Servlet文件 3 jsp基于ja
  • 给本科实验室的分享PPT续-回复各种问题

    谢邀 该分享主要面向实验室的大一 大二同学
  • Neo4J(Cypher语句)初识

    欢迎各路大神临幸寒舍 以下节点标签为people friend 用户自己也可以设置成其他标签 查询时需要用到标签 这个标签可以类比为关系数据库中的表名 创建节点 关系 创建节点 小明 create n people name 小明 age
  • FFmpeg音频处理——音频混合、拼接、剪切、转码

    接触FFmpeg有一段时间了 它是音视频开发的开源库 几乎其他所有播放器 直播平台都基于FFmpeg进行二次开发 本篇文章来总结下采用FFmpeg进行音频处理 音频混合 音频剪切 音频拼接与音频转码 采用android studio进行开发
  • 一篇搞定React生命周期以及执行顺序 v16.8+(前端面试整理)

    React 组件生命周期 从事前端工作已经有一段时间 最近在面试求职者的时候发现 React最基础的实例生命周期都说不清楚 也不能说清楚每个生命周期方法具体作用 所以我通过代码 官网文档的形式总结下文 React生命周期可以说是react最
  • Ubuntu和windows系统下安装odoo16 社区版和企业版附带安装视频

    Ubuntu安装视频 ubuntu下安装odoo16社区版和企业版 Windows10安装视频 windows10安装odoo16社区版和企业版不成功的看这个视频 还是和以前的类似 先用官方的方法安装社区版 然后企业版源码覆盖掉社区版源码就
  • 数据结构 —— 线索二叉树

    线索二叉树的意义 对于一个有n个节点的二叉树 每个节点有指向左右孩子的指针域 其中会出现n 1个空指针域 这些空间不储存任何事物 浪费着内存的资源 对于一些需要频繁进行二叉树遍历操作的场合 二叉树的非递归遍历操作过程相对比较复杂 递归遍历虽