数据结构与算法---线索化二叉树(Threaded BinaryTree)
先看一个问题
将数列 {1, 3, 6, 8, 10, 14 } 构建成一颗二叉树
问题分析:
- 当我们对上面的二叉树进行中序遍历时,数列为 {8, 3, 10, 1, 6, 14 }
- 但是 6, 8, 10, 14 这几个节点的 左右指针,并没有完全的利用上.
- 如果我们希望充分的利用 各个节点的左右指针, 让各个节点可以指向自己的前后节点,怎么办?
- 解决方案-线索二叉树
线索二叉树基本介绍
1、n个结点的二叉链表中含有n+1 【公式 2n-(n-1)=n+1】 个空指针域。利用二叉链表中的空指针域,存放指向该结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索")
2、这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种
3、一个结点的前一个结点,称为前驱结点
4、一个结点的后一个结点,称为后继结点
线索二叉树应用案例
应用案例说明:将下面的二叉树,进行中序线索二叉树。中序遍历的数列为 {8, 3, 10, 1, 14, 6}
思路分析: 中序遍历的结果:{8, 3, 10, 1, 14, 6}
说明: 当线索化二叉树后,Node节点的 属性 left 和 right ,有如下情况:
- left 指向的是左子树,也可能是指向的前驱节点. 比如 ① 节点 left 指向的左子树, 而 ⑩ 节点的 left 指向的就是前驱节点.
- right指向的是右子树,也可能是指向后继节点,比如 ① 节点right 指向的是右子树,而⑩ 节点的right 指向的是后继节点.
代码实现:
- class BinaryTree {
- private HeroNode root;
- privateHeroNode pre=null;
- public void threadNodes() {
- threadNodes(root);
- }
- public void threadNodes(HeroNode node) {
- if(node==null) {
- return;
- }
- threadNodes(node.getLeft());
- if(node.getLeft()==null){
- node.setLeft(pre);
- node.setLeftType(1);
- }
- if(pre!=null&&pre.getRight()==null) {
- pre.setRight(node);
- pre.setRightType(1); }
- pre=node;
- threadNodes(node.getRight());}}
代码
- public class BinaryTreeDemo {
- public static void main(String[] args) {
- BinaryTree binaryTree = new BinaryTree();
- HeroNode root = new HeroNode(1, "jack");
- HeroNode node1 = new HeroNode(3, "tom");
- HeroNode node2 = new HeroNode(6, "mike");
- root.setLeftNode(node1);
- root.setRightNode(node2);
- binaryTree.setRoot(root);
- HeroNode node3 = new HeroNode(8, "林冲");
- HeroNode node4 = new HeroNode(10, "关胜");
- node1.setLeftNode(node3);
- node1.setRightNode(node4);
- HeroNode node5 = new HeroNode(14, "jerry");
- node2.setLeftNode(node5);
- System.out.println("---中序---");
- binaryTree.infixOrder();
- //中序线索化二叉树
- binaryTree.threadNodes();
- HeroNode afterHeroNode10 = node4.getRight();
- System.out.println(afterHeroNode10);// no=1 name=jack ok了
- }}
测试
遍历线索化二叉树
说明:对前面的中序线索化的二叉树, 进行遍历
分析:因为线索化后,各个结点指向有变化,因此原来的遍历方式不能使用,这时需要使用新的方式遍历线索化二叉树,各个节点可以通过线型方式遍历,因此无需使用递归方式,这样也提高了遍历的效率。遍历的次序应当和中序遍历保持一致。
- //遍历线索化二叉树的方法
- public void threadedList() {
- //定义一个变量,存储当前遍历的结点,从root开始
- HeroNode node = root;
- while(node != null) {
- //循环的找到leftType == 1的结点,第一个找到就是8结点
- //后面随着遍历而变化,因为当leftType==1时,说明该结点是按照线索化
- //处理后的有效结点
- while(node.getLeftType() == 0) {
- node = node.getLeft();
- }
- //打印当前这个结点
- System.out.println(node);
- //如果当前结点的右指针指向的是后继结点,就一直输出
- while(node.getRightType() == 1) {
- //获取到当前结点的后继结点
- node = node.getRight();
- System.out.println(node);
- }
- //替换这个遍历的结点
- node = node.getRight();
- }
- }
代码
- public static void main(String[] args) {
- //测试一把中序线索二叉树的功能
- HeroNode root = new HeroNode(1, "tom");
- HeroNode node2 = new HeroNode(3, "jack");
- HeroNode node3 = new HeroNode(6, "smith");
- HeroNode node4 = new HeroNode(8, "mary");
- HeroNode node5 = new HeroNode(10, "king");
- HeroNode node6 = new HeroNode(14, "dim");
- //二叉树,后面我们要递归创建, 现在简单处理使用手动创建
- root.setLeft(node2);
- root.setRight(node3);
- node2.setLeft(node4);
- node2.setRight(node5);
- node3.setLeft(node6);
- //测试中序线索化
- ThreadedBinaryTree threadedBinaryTree = new ThreadedBinaryTree();
- threadedBinaryTree.setRoot(root);
- threadedBinaryTree.threadedNodes();
- //测试: 以10号节点测试
- HeroNode leftNode = node5.getLeft();
- HeroNode rightNode = node5.getRight();
- System.out.println("10号结点的前驱结点是 =" + leftNode); //
- System.out.println("10号结点的后继结点是=" + rightNode); //1
- //当线索化二叉树后,能在使用原来的遍历方法
- //threadedBinaryTree.infixOrder();
- System.out.println("使用线索化的方式遍历 线索化二叉树");
- threadedBinaryTree.threadedList(); // 8, 3, 10, 1, 14, 6
- }
测试
数据结构与算法---线索化二叉树(Threaded BinaryTree)的更多相关文章
- C#数据结构-线索化二叉树
为什么线索化二叉树? 对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上,否则我们只知道后续的左右子树.现在我们充分利用二叉树左右子树的空节点,分别指向当前节点的前驱.后继,便 ...
- 线索化二叉树的构建与先序,中序遍历(C++版)
贴出学习C++数据结构线索化二叉树的过程, 方便和我一样的新手进行测试和学习 同时欢迎各位大神纠正. 不同与普通二叉树的地方会用背景色填充 //BinTreeNode_Thr.h enum Point ...
- 图解前序遍历线索化二叉树,前序线索二叉树遍历,C\C++描述
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 图解中序遍历线索化二叉树,中序线索二叉树遍历,C\C++描述
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 后序线索化二叉树(Java版)
前面介绍了前序线索化二叉树.中序线索化二叉树,本文将介绍后序线索化二叉树.之所以用单独的一篇文章来分析后序线索化二叉树,是因为后序线索化二叉树比前序.中序要复杂一些:另外在复习线索化二叉树的过程中,大 ...
- JAVA递归实现线索化二叉树
JAVA递归实现线索化二叉树 基础理论 首先,二叉树递归遍历分为先序遍历.中序遍历和后序遍历. 先序遍历为:根节点+左子树+右子树 中序遍历为:左子树+根节点+右子树 后序遍历为:左子树+右子树+根节 ...
- YTU 3026: 中序线索化二叉树
原文链接:https://www.dreamwings.cn/ytu3026/2896.html 3026: 中序线索化二叉树 时间限制: 1 Sec 内存限制: 128 MB 提交: 9 解决: ...
- Java 内功修炼 之 数据结构与算法(一)
一.基本认识 1.数据结构与算法的关系? (1)数据结构(data structure): 数据结构指的是 数据与数据 之间的结构关系.比如:数组.队列.哈希.树 等结构. (2)算法: 算法指的是 ...
- JS数据结构与算法 - 二叉树(一)基本算法
仅供JavaScript刷题参考用. 二叉查找树和平衡二叉树 其它树:满二叉树.完全二叉树.完美二叉树.哈弗曼树.二叉查找树BST.平衡二叉树AVL 了解:红黑树,是一种特殊的二叉树.这种树可以进行高 ...
随机推荐
- WPF滚动条嵌套,响应鼠标滑轮事件的处理
在C# 中,两个ScrollViewer嵌套在一起或者ScrollViewer里面嵌套一个ListBox.Listview(控件本身有scrollviewer)的时候,我们本想要的效果是鼠标滚动整个S ...
- github page的两种类型
1. 什么是Github ? Github 官方主页 简单说,Github是一个基于git的社会化代码分享社区. 你可以在Github上创建免费的远程仓库(remote repository),分享你 ...
- Delphi Android 将Google ZXing 整合(调用Jar文件)
前篇文章介绍了在delphi App(以下简称App)中可使用intent来调用Google ZXing 条码扫描器(以下简称zx),其各有优缺点,优点是我们不需关注zx本身的细节,只需调用其接口即可 ...
- Win8Metro(C#)数字图像处理--2.5图像亮度调整
原文:Win8Metro(C#)数字图像处理--2.5图像亮度调整 2.5图像亮度调整函数 [函数名称] 图像亮度调整函数BrightnessAdjustProcess(WriteableBit ...
- mysql的命令行安装,忘记密码,密码重置问题
1.下载,安装msi 2.在MYSQL安装目录下,新建data目录 3.进入MYSQL的安装目录下,新建一个默认配置文件my.ini [mysql] # 设置mysql客户端默认字符集 default ...
- 程序定义了多个入口点。使用 /main (指定包含入口点的类型)进行编译
原文:请使用/main进行编译,以指定包含入口点类型 在使用VS工具初学C#的时候需要不停的写小程序,觉得每次都新建项目太过麻烦,所以试着把程序写在一个项目下面,结果编译的时候出错了,因为我每个小程序 ...
- Win10《芒果TV》商店版更新v3.2.4:新增跨年事件直播、电视台直播,新年快乐
听说半个娱乐圈都来了,<芒果TV>UWP版邀您一起,于2016年12月31日晚,观看<湖南卫视2016·2017跨年演唱会>直播,请更新v3.2.4版,主要新增大事件直播和电视 ...
- EnterpriseLibrary 6.0 AOP 使用问题
因为EnterPrise Library 6.0改动了模块的功能类不再自动从Unity创建了,也就是引导也不依赖Unity容器组件,需要先使用静态方法注册一下 private static void ...
- Delphi中Menu设置Images属性后快捷按键下划线被隐藏解决方法
现象:MainMenu设置Images属性后,看不到快捷按键的下划线,如:新建(&N) 分析:VCL中Menus.pas单元的代码,看到如下语句procedure TMenuItem.Adva ...
- Windows窗体原理及控件WM_DRAWITEM和子类化重绘演示文件
http://download.csdn.net/detail/wenzhou1219/6783959