【数据结构与算法】线索二叉树

文章目录

  • 线索二叉树
    • 线索二叉树的结点存储结构
  • 二叉树线索化
    • 先序线索化
      • 递归实现
    • 中序线索化
      • 递归实现
    • 后续线索化
      • 递归实现
  • 线索二叉树的遍历
    • 先序线索二叉树的遍历
    • 中序线索二叉树的遍历
    • 后续线索二叉树的遍历

线索二叉树

传统的二叉链表存储二叉树,仅能表示一种父子关系,不能直接得到结点在遍历过程中的前驱和后继,而且,有n个结点的二叉树使用二叉链表存储时,存在n+1个空指针。因此有人猜想能否利用这些空指针来存放其遍历前驱或遍历后继的指针,用来加快查找结点前驱和后继的速度?于是,线索二叉树诞生了。

线索二叉树规定:

  • 若结点无左孩子,则令lchild指向其遍历前驱。
  • 若结点无右孩子,则令rchlid指向其遍历后继。

当然,为了表明判断结点无左左孩子、无右孩子,因此线索二叉树还需要增加了两个标识,ltag和rtag来表明结点是否存在左孩子、右孩子。

线索二叉树的结点存储结构

// C++class ThreadNode{
public:// 这里省略数据域ThreadNode *lchild, *rchild;bool ltag,rtag;
};

以这种结点构成的二叉链表作为二叉树的存储结构,我们称为线索链表。

其中指向结点遍历前驱和遍历后继的指针我们称为线索

加上线索的二叉树,我们称为线索二叉树。

二叉树线索化

二叉树的线索化是指将二叉链表中的空指针改为指向遍历前驱或遍历后继的线索。

因为遍历前驱和遍历后继的信息只有在遍历时才能够得到,因此线索化的实质就是遍历一次二叉树。

先序线索化

递归实现

/*** @param *pre 前一个结点* @param *node 当前结点 */
void inThread(ThreadNode *node, ThreadNode *pre) {if (node == nullptr)return;if (node->lchild == nullptr) {// 当前结点的左孩子为空,则当前结点的遍历前驱为前一个结点node->lchild = pre;node->ltag = true;}if (pre != nullptr && pre->rchild == nullptr){// 前一个结点的右孩子为空,则前一个结点的遍历后继为当前结点pre->rchild = node;pre->rtag = true;}pre = node;inThread(node->lchild, pre);inThread(node->rchild, pre);
}

中序线索化

递归实现

// C++/*** @param *pre 前一个结点* @param *node 当前结点 */
void inThread(ThreadNode *node, ThreadNode *pre) {if (node == nullptr)return;inThread(node->lchild, pre);if (node->lchild == nullptr) {node->lchild = pre;node->ltag = true;}if (pre != nullptr && pre->rchild == nullptr){pre->rchild = node;pre->rtag = true;}pre = node;inThread(node->rchild, pre);
}

后续线索化

递归实现


/*** @param *pre 前一个结点* @param *node 当前结点 */
void inThread(ThreadNode *node, ThreadNode *pre) {if (node == nullptr)return;inThread(node->lchild, pre);inThread(node->rchild, pre);if (node->lchild == nullptr) {node->lchild = pre;node->ltag = true;}if (pre != nullptr && pre->rchild == nullptr){pre->rchild = node;pre->rtag = true;}pre = node;
}

线索二叉树的遍历

有序线索二叉树中包含了线索,因此,我们只需要按照线索进行遍历即可。下面给出不带头结点的线索二叉树的遍历。

先序线索二叉树的遍历

void foreach(ThreadNode *node) {ThreadNode *p = node;while (p != nullptr) {visit(node);// 有左孩子,左孩子是后继if(!p->ltag) p = p->lchild;// 无左孩子有右孩子,右孩子是后继else if(!p->rtag) p = p->rchild;// 叶结点的右孩子是线索,指向后继else p = p->rchild;}
}

中序线索二叉树的遍历

void foreach(ThreadNode *node) {ThreadNode *p = node;while (p != nullptr) {while(!p->ltag) p = p->lchild;visit(p);while(p->rtag) {p = p->rchild;visit(p);}p=p->rchild;}
}

后续线索二叉树的遍历

后续线索二叉树中查找结点的后继较为复杂,有以下几种情况:

  1. 若结点x是二叉树的根,则后继为空
  2. 若结点x是其双亲的右孩子,则其后继为双亲结点。
  3. 若结点x是其双亲的左孩子,且其双亲没有右孩子,则其后继为双亲结点。
  4. 若结点x是其双亲的左孩子,且其双亲有右子树,则其后继为右子树上按后续遍历列出的第一个结点。

依据4,我们可以知道,对于有左右孩子的双亲结点来说,它的后继是无法直接找到的。因此如果在后续线索二叉树上查找后继时,还需要知道双亲结点。我们可以采用带标志域的三叉链表作为存储结构。

class ThreadNode {
public:// 这里省略数据域// parent指向该节点的双亲结点,需要在新增结点时指定ThreadNode *lchild, *rchild, *parent;bool ltag, rtag;
};

使用带标志域的三叉链表存储的后续线索二叉树的遍历算法待补充

未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/23249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC会带来失业潮吗?紧紧跟时代第一步,如何学习AIGC

会,但AI淘汰的始终是跟不上时代的人。 现在很多公司都有AI培训,不仅GPT,还有Midjourney、Stable DIffusion等一系列AI工具。 像我们公司虽然今年招的少,但也会对新招的应届生统一进行AI培训。 用任正非先生的话来说就是&#x…

charles抓包工具之---添加vConsole

Charles Rewrite重写(详解&#xff01;必懂系列)-CSDN博客 chales 重写/断点/映射/手机代理/其他主机代理_charles 批量映射-CSDN博客 在 Charles 上添加 rewrite 规则&#xff0c;以便在响应的 <head> 部分添加 vConsole&#xff0c;可以按照以下步骤操作&#xff1a;…

【ARM】PK51-如何添加芯片型号的方法

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 遇到打开工程提示没有该芯片设备提示如何解决。 2、 问题场景 客户发来一个工程文件&#xff0c;打开后软件提示没有发现该芯片设备提示。 图 1 3、软硬件环境 1&#xff09;、软件版本&#xff1a;keil μvision…

弗莱明发现青霉素

1945年&#xff0c;弗莱明因青霉素获诺贝尔医学奖。在弗莱明之前有多人注意到了青霉能抑制细菌的生长&#xff0c;但是他们没有一个人像弗莱明那样做进一步的更深入的研究&#xff0c;更没有一个人像弗莱明那样确定了这个特殊的现象是由于青霉分泌的某种物质所致。所以&#xf…

CAD入门基础

一&#xff0c;新建一个CAD文件 1.新建文件 2.保存为.dwt文件 3.画直线 点击直线图标画直线&#xff0c;选中直线出现高亮&#xff0c;点击左键&#xff0c;出现" 取消 " 就是可以画下一条线段了 " 删除"就可以了删除了。 3、直接删除法 1. 首先&#xf…

Yolov10环境配置+训练自己数据集(Windows10)

1、环境: 1.1硬件环境: 显卡:GTX 1650 Supper cuda:10.2.89_441.22_win10 cudnn:10.2-windows10-x64-v8.0.4.30 需要使用英伟达显卡安装显卡驱动,根据显卡驱动的版本安装cuda和cudnn, 针对NVIDIA显卡,已安装驱动情况下,使用nvidia-smi命令可以非常方便查看显卡类型…

npm如何发布自己的插件包

npm如何发布自己的插件包 1、注册NPM账号&#xff1a; 如果你还没有NPM账号&#xff0c;你需要在https://www.npmjs.com/上注册一个。 2、登录NPM&#xff1a; 在命令行中运行npm adduser&#xff0c;并按照提示输入你的用户名、密码和邮箱。 3、初始化项目&#xff1a; …

【C++】C++提供类型转换的机制

目录 前言&#xff1a; 一&#xff0c;static_cast 二&#xff0c;reinterpret_cast 三&#xff0c;const_cast 四&#xff0c;dynamic_cast 前言&#xff1a; 传统的不同类型转换有隐式类型转换&#xff08;类型不匹配时编译器自动进行的转换&#xff0c;如&#xff1a;i…

Simulink建立4WIS线性二自由度参考模型

4WIS线性二自由度参考模型 基于前轮转向做了小改动&#xff0c;难度不大&#xff0c;相当于两个微分方程加了两项 Simulink向CarSim中输入四个车轮的转角 有一点注意&#xff0c;四轮转向&#xff0c;前后轴车轮转角不应相等&#xff0c;否则动画会很滑稽 同侧车轮转向角的大小…

各种内部排序算法的比较及应用(插入排序、交换排序、选择排序、归并排序、基数排序)

目录 内部排序 前言 1.内部排序算法的比较 1.1各种排序算法的特点、比较和适用场景 1.2排序算法的稳定性判断及改进 1.3更适合采用顺序存储的排序算法 1.4根据排序的中间过程判断所采用的排序算法 1.5各种排序算法的性质 2.内部排序算法的应用 2.1选取排序算法时需要…

UE4_Ben_图形52_水下效果处理

学习笔记&#xff0c;不喜勿喷&#xff0c;欢迎指正&#xff0c;侵权立删&#xff01;祝愿生活越来越好&#xff01; 在这个后期处理的效果中&#xff0c;我们可以看到有很多不同的&#xff0c;这里有浓雾&#xff0c;波纹扭曲&#xff0c;镜头扭曲和边缘模糊&#xff0c;在第4…

pcb实验六-元件设计

目录 一&#xff0c;绘制28管脚PLCC封装ATF750C-10JC元件 二&#xff0c;绘制变压器原理图符号&#xff0c;并生成各种库文件输出报表 1&#xff0c;绘制变压器原理图 2&#xff0c;添加封装 3&#xff0c;输出报表文件 三&#xff0c;绘制音乐集成芯片及LCD元件 1&…

Apache漏洞复现:【CVE-2021-42013】【CVE_2021_41773】【CVE-2017-15715】

声明 严禁读者利用本文介绍知识点对网站进行非法操作 , 本文仅用于技术交流和学习 , 如果您利用文章中介绍的知识对他人造成损失 , 后果由您自行承担 , 如果您不能同意该约定 , 请您务必不要阅读该文章 , 感谢您的配合 ! 远程代码执行 CVE-2021-42013 描述 Apache HTTP Ser…

R语言数据探索和分析21-中国GDP及其影响因素多元线性回归分析

一、研究背景和意义 GDP 是宏观经济中最受关注的经济统计数字&#xff0c;目前我国国内生产总值年均增长率均明显高于同期美、日等发达经济体和巴 西、俄罗斯、南非、印度等其他金砖国家&#xff0c;成为世界经济增长的主力军&#xff0c;GDP 的增长对一个国家有着十分重要的意…

kettle学习总结(7)

书接上回&#xff0c;该章节主要是数据同步&#xff0c;脚本如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <transformation><info><name>sync_sp-dev</name><description /><extended_description /…

Git 完整操作之记录

目录 一 . Git 基本操作流程及示例代码 1. 初始化 Git 仓库 2. 克隆远程仓库 3. 检查当前状态 4. 添加文件到暂存区 5. 提交更改 6. 查看提交历史 7. 创建分支 8. 切换分支 9. 合并分支 10. 推送更改到远程仓库 11. 拉取远程仓库的更改 12. 回滚到上一个版本 二…

mysql中事务的简介

大家好。我们在日常开发过程中肯定都或多或少的用到过事务&#xff0c;而且在面试时&#xff0c;数据库的事务也是必问内容之一。今天我们就来说说mysql的事务。 为了方便我们下面内容的讲解&#xff0c;我们也先建立一个讲事务必用的表–account表&#xff0c;并在表中插入两…

基于centos7打包当前环境的系统为iso镜像文件

1. 准备工作 1.下载安装mondo 切换到root用户&#xff0c;进入yum下载库 # cd /etc/yum.repos.d # wget ftp://ftp.mondorescue.org/centos/7/x86_64/mondorescue.repo 打开文件mondorescue.repo&#xff0c;修改gpgcheck属性为0&#xff0c;指定mondorescue.repo安装 # 安…

【Python数据挖掘实战案例】机器学习LightGBM算法原理、特点、应用---基于鸢尾花iris数据集分类实战

一、引言 1、简要介绍数据挖掘的重要性和应用 在数字化时代&#xff0c;数据已经成为企业和社会决策的重要依据。数据挖掘作为一门交叉学科&#xff0c;结合了统计学、机器学习、数据库技术和可视化等多个领域的知识&#xff0c;旨在从海量数据中提取有价值的信息&#xff0c…

生命在于学习——Python人工智能原理(3.2)

三、深度学习 &#xff08;二&#xff09;人工神经网络 人工神经网络是模仿人类大脑神经系统工作原理所创建的数学模型&#xff0c;有并行的分布处理能力、高容错性和自我学习等特征。 1、感知器 感知器由Frank Roseblatt于1957年提出&#xff0c;是一种广泛使用的线性分类…