JAVA递归实现线索化二叉树

基础理论

首先,二叉树递归遍历分为先序遍历、中序遍历和后序遍历。

先序遍历为:根节点+左子树+右子树

中序遍历为:左子树+根节点+右子树

后序遍历为:左子树+右子树+根节点

(只要记住根节点在哪里就是什么遍历,且都是先左再右)

线索化

现在有这么一棵二叉树,它的数据结构由左节点+权+右节点构成。

可以看到4,5,6,7这几个节点的左右节点空间被浪费了。因此,线索化是指有效利用这些空间。

中序遍历的顺序为:4 2 5 1 6 3 7

现在引入前驱节点以及后继节点。

前驱节点:线索化二叉树时,一个节点的前一个节点

后继节点:线索化二叉树时,一个节点的后一个节点

(例如下图:根据中序遍历,5的前驱节点是2 , 5的后继节点是1)

(中序遍历)实现线索化二叉树

定义数据结构ThreadedNode

	//节点的权
int value;
//左儿子
ThreadedNode leftNode;
//右儿子
ThreadedNode rightNode;
//标识指针类型,其中0,1分别表示有无线索化,默认为0
int leftType;
int rightType;

中序遍历

//中序遍历
public void midShow() {
//左子节点
if(leftNode!=null) {
leftNode.midShow();
}
//当前节点
System.out.println(value);
//右子节点
if(rightNode!=null) {
rightNode.midShow();
}
}

这里使用递归的方式来实现。我们先把问题简单化,只看红圈的部分,如下图

定义一个节点pre用来存储当前节点,类似指针。

从根节点1开始递归,如果当前节点为空,返回,到4,此时4的前驱结点为null,结点5的前驱结点为2

遍历到5的时候指向前驱结点2,前驱结点2为上一层递归的指针,因此指向它的前驱结点就行,再把左指针类型置为1

如果当前节点的前驱结点pre的右指针为null,则将它设置为当前节点,此时即4的后继结点为2,并将右指针类型置为1

每处理一个节点,当前节点是下一个节点的前驱节点

线索化二叉树ThreadedBinaryTree


//中序线索化二叉树
public void threadNodes() {
threadNodes(root);
} public void threadNodes(ThreadedNode node) {
//当前节点如果为null,直接返回
if(node==null) {
return;
}
//处理前驱节点
if(node.leftNode==null){
//让当前节点的左指针指向前驱节点
node.leftNode=pre;
//改变当前节点左指针的类型
node.leftType=1;
}
//处理前驱的右指针,如果前驱节点的右指针是null(没有指下右子树)
if(pre!=null&&pre.rightNode==null) {
//让前驱节点的右指针指向当前节点
pre.rightNode=node;
//改变前驱节点的右指针类型
pre.rightType=1;
}
//每处理一个节点,当前节点是下一个节点的前驱节点
pre=node;
}

现在再把上面这段代码按照中序遍历的方式放在中间,进行递归

		//当前节点如果为null,直接返回
if(node==null) {
return;
}
//处理左子树
threadNodes(node.leftNode);
//----------------------------------------------------------
//处理前驱节点
if(node.leftNode==null){
//让当前节点的左指针指向前驱节点
node.leftNode=pre;
//改变当前节点左指针的类型
node.leftType=1;
}
//处理前驱的右指针,如果前驱节点的右指针是null(没有指下右子树)
if(pre!=null&&pre.rightNode==null) {
//让前驱节点的右指针指向当前节点
pre.rightNode=node;
//改变前驱节点的右指针类型
pre.rightType=1;
}
//每处理一个节点,当前节点是下一个节点的前驱节点
pre=node;
//-----------------------------------------------------------
//处理右子树
threadNodes(node.rightNode);
}

现在编写测试方法

package demo7;

public class TestThreadedBinaryTree {

	public static void main(String[] args) {
//创建一颗树
ThreadedBinaryTree binTree = new ThreadedBinaryTree();
//创建一个根节点
ThreadedNode root = new ThreadedNode(1);
//把根节点赋给树
binTree.setRoot(root);
//创建一个左节点
ThreadedNode rootL = new ThreadedNode(2);
//把新创建的节点设置为根节点的子节点
root.setLeftNode(rootL);
//创建一个右节点
ThreadedNode rootR = new ThreadedNode(3);
//把新创建的节点设置为根节点的子节点
root.setRightNode(rootR);
//为第二层的左节点创建两个子节点
rootL.setLeftNode(new ThreadedNode(4));
ThreadedNode fiveNode = new ThreadedNode(5);
rootL.setRightNode(fiveNode);
//为第二层的右节点创建两个子节点
rootR.setLeftNode(new ThreadedNode(6));
rootR.setRightNode(new ThreadedNode(7));
//中序遍历树
binTree.midShow();
System.out.println("===============");
//中前线索化二叉树
binTree.threadNodes();
binTree.threadIterate();
} }

JAVA递归实现线索化二叉树的更多相关文章

  1. 后序线索化二叉树(Java版)

    前面介绍了前序线索化二叉树.中序线索化二叉树,本文将介绍后序线索化二叉树.之所以用单独的一篇文章来分析后序线索化二叉树,是因为后序线索化二叉树比前序.中序要复杂一些:另外在复习线索化二叉树的过程中,大 ...

  2. 图解中序遍历线索化二叉树,中序线索二叉树遍历,C\C++描述

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  3. 数据结构与算法---线索化二叉树(Threaded BinaryTree)

    先看一个问题 将数列 {1, 3, 6, 8, 10, 14  } 构建成一颗二叉树 问题分析: 当我们对上面的二叉树进行中序遍历时,数列为 {8, 3, 10, 1, 6, 14 } 但是 6, 8 ...

  4. YTU 3026: 中序线索化二叉树

    原文链接:https://www.dreamwings.cn/ytu3026/2896.html 3026: 中序线索化二叉树 时间限制: 1 Sec  内存限制: 128 MB 提交: 9  解决: ...

  5. 线索化二叉树的构建与先序,中序遍历(C++版)

    贴出学习C++数据结构线索化二叉树的过程, 方便和我一样的新手进行测试和学习 同时欢迎各位大神纠正. 不同与普通二叉树的地方会用背景色填充 //BinTreeNode_Thr.h enum Point ...

  6. 图解前序遍历线索化二叉树,前序线索二叉树遍历,C\C++描述

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  7. C#数据结构-线索化二叉树

    为什么线索化二叉树? 对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上,否则我们只知道后续的左右子树.现在我们充分利用二叉树左右子树的空节点,分别指向当前节点的前驱.后继,便 ...

  8. Java递归列出目录下全部文件

    Java递归列出目录下全部文件 /** * 列出指定目录的全部内容 * */ import java.io.*; class hello{ public static void main(String ...

  9. Java 递归调用 recursive 给一个参数 返回一大堆

    需求: 需要组装成对象多层嵌套式的 json字符串; 想到使用 递归来完成这个多层嵌套: 憋了四个小时,终于写出来了; 先看效果: 数据库中的数据: 拼装后的效果: [ EmpVO{ ename='孙 ...

随机推荐

  1. 单链表的前K个的逆序输出

    单链表逆序输出也是常被面试官问到题算法题,所以自己就总结了一下,在此贴出算法,与小伙伴们相互交流. 首先要有三个指针,前两个分别指向首节点,首节点的下一个节点,第三个是临时指针,是为了储存首节点的下一 ...

  2. 分布式系统监视zabbix讲解五之web监控

    Web 监控 概况 你可以使用 Zabbix 检查几个网站可用性方面. 如果要使用 Web 检测功能,必须在 编译Zabbix 的时候加入 cURL(libcurl) 的支持. 要使用 Web 监控, ...

  3. MATLAB 与 Excel 接口

    MATLAB 与 Excel 接口MATLAB 与 Excel 有两种接口方式:一种是通过 MATLAB 提供的 Excel 生成器,生成220 MATLAB 实用教程DLL 组件和 VBA 代码,实 ...

  4. 为什么安装了MinGW之后,还是不能在Matlab中使用mex?

    原文地址:http://blog.sina.com.cn/s/blog_53c7b1580102xjcw.html 老版本的Matlab自带lcc,在Matlab中输入mex -setup就可以选择. ...

  5. outh2

    之前做天猫精灵对接,就碰到了outh鉴权,当时实现好之后没有细细缕,今天看了一个博主的介绍,贴一下 转载自http://www.ruanyifeng.com/blog/2014/05/oauth_2_ ...

  6. 【Java并发编程】synchronized相关面试题总结

    目录 说说自己对于synchronized关键字的了解 synchronized关键字的三种使用 synchronized关键字的底层原理 JDK1.6之后对synchronized关键字进行的优化 ...

  7. 关于KeePass实现mstsc远程桌面(rdp协议)的自动登录

    本文的Keepass版本:KeePass Password Safe Version 2.45 首先介绍一下Keepass,引用官网的解释如下: KeePass is a free open sour ...

  8. JVM学习(四)JVM调优

    一.调优命令 Sun JDK监控和故障处理命令有jps.jstat.jmap.jhat.jstack.jinfo jps,JVM Process Status Tool,显示指定系统内所有的HotSp ...

  9. Layer层自定义

    keras允许自定义Layer层, 大大方便了一些复杂操作的实现. 也方便了一些novel结构的复用, 提高搭建模型的效率. 实现方法 通过继承keras.engine.Layer类, 重写其中的部分 ...

  10. 听说这四个概念,很多 Java 老手都说不清

    Java 是很多人一直在用的编程语言,但是有些 Java 概念是非常难以理解的,哪怕是一些多年的老手,对某些 Java 概念也存在一些混淆和困惑. 所以,在这篇文章里,会介绍四个 Java 中最难理解 ...