图解

代码实现

package com.atguigu.tree.threadedbinarytree;/*** @创建人 wdl* @创建时间 2021/3/25* @描述*/
public class ThreadedBinaryTreeDemo {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);//当线索化二叉树后System.out.println("使用线索化的方式遍历 线索化二叉树");threadedBinaryTree.threadedList();//8,3,10,1,14,6}}//定义ThreadedBinaryTree实现了线索化功能的二叉树
class ThreadedBinaryTree{private HeroNode root;//为了实现线索化,需要创建一个指向当前节点的前驱节点的指针//在递归进行线索化是,pre总是保留前一个节点private HeroNode pre=null;public void setRoot(HeroNode root){this.root=root;}//重载threadedNodes方法public void threadedNodes(){this.threadedNodes(root);}//遍历线索化二叉树的方法public void threadedList(){//定义一个变量,存储当前遍历的节点,从root开始HeroNode node=root;while (node!=null){//循环的扎到leftType==1的节点,第一个找到的就是8节点//后面会随着遍历而变化,因为当lefType==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();}}//编写对二叉树进行中序线索化的方法/**** @param node 就是当前需要线索化的节点*/public void threadedNodes(HeroNode node){//如果node==null,不能线索化if(node==null){return;}//1.先线索化左子树threadedNodes(node.getLeft());//2.线索化当前节点[有难度]//处理当前节点的前驱节点//以8节点来理解//8节点的.left=null,8节点的.leftType=1if(node.getLeft()==null){//当前节点的左指针指向前驱节点node.setLeft(pre);//修改当前节点的左指针的类型,指向前驱节点node.setLeftType(1);}//处理当前节点的后继节点if(pre!=null&&pre.getRight()==null){//让前驱节点的右指针指向当前节点pre.setRight(node);//修改前驱节点的右指针类型pre.setRightType(1);}//!!!每处理一个节点,让当前节点是下一个节点的前驱节点pre=node;//3.再线索化右子树threadedNodes(node.getRight());}//删除节点public void delNode(int no){if(root!=null){//如果只有一个root接地那,这里立即判断root是不是就是要删除的节点if(root.getNo()==no){root=null;}else {//递归删除root.delNode(no);}}else {System.out.println("空树,不能删除");}}//前序遍历public void preOrder(){if(this.root!=null){this.root.preOrder();}else {System.out.println("二叉树为空,无法遍历");}}//中序遍历public void infixOrder(){if(this.root!=null){this.root.infixOrder();}else {System.out.println("二叉树为空,无法遍历");}}//后序遍历public void postOrder(){if(this.root!=null){this.root.postOrder();}else {System.out.println("二叉树为空,无法遍历");}}//前序查找public HeroNode preOrderSearch(int no){if(root!=null){return root.preOrderSearch(no);}else {return null;}}//中序查找public HeroNode infixOrderSearch(int no){if(root!=null){return root.infixOrderSearch(no);}else {return null;}}//后序查找public HeroNode postOrderSearch(int no){if(root!=null){return root.postOrderSearch(no);}else {return null;}}}//先创建HeroNode节点
class HeroNode{private int no;private String name;private HeroNode left;//默认为nullprivate HeroNode right;//默认为null//说明//1.如果leftType==0表示指向的是左子树,如果是1则表示指向前驱节点//2.如果rightType==0表示指向的是右子树,如果是1则表示指向后继节点private int leftType;private int rightType;public int getLeftType() {return leftType;}public void setLeftType(int leftType) {this.leftType = leftType;}public int getRightType() {return rightType;}public void setRightType(int rightType) {this.rightType = rightType;}public HeroNode(int no, String name) {super();this.no = no;this.name = name;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}public HeroNode getLeft() {return left;}public void setLeft(HeroNode left) {this.left = left;}public HeroNode getRight() {return right;}public void setRight(HeroNode right) {this.right = right;}@Overridepublic String toString() {return "HeroNode{" +"no=" + no +", name='" + name + '\'' +'}';}//递归删除节点//1.如果删除的节点是叶子节点,则删除该节点//2.如果删除的节点是非叶子节点,则删除该子树public void delNode(int no){if(this.left!=null&&this.left.no==no){this.left=null;return;}if(this.right!=null&&this.right.no==no){this.right=null;return;}if(this.left!=null){this.left.delNode(no);}if(this.right!=null){this.right.delNode(no);}}//编写前序遍历的方法public void preOrder(){System.out.println(this);//先输出父节点//递归向左子树前序遍历if(this.left!=null){this.left.preOrder();}//递归向右子树前序遍历if(this.right!=null){this.right.preOrder();}}//中序遍历public void infixOrder(){//递归向左子树中序遍历if(this.left!=null){this.left.infixOrder();}System.out.println(this);//输出父节点//递归向右子树中序遍历if(this.right!=null){this.right.infixOrder();}}//后序遍历public void postOrder(){//递归向左子树后序遍历if(this.left!=null){this.left.postOrder();}//递归向右子树后序遍历if(this.right!=null){this.right.postOrder();}System.out.println(this);//输出父节点}/**** @param no 查找no* @return 如果找到就返回该Node,如果没有找到返回null*///前序遍历查找public HeroNode preOrderSearch(int no){System.out.println("进入前序查找");//比较当前节点是不是if(this.no==no){return this;}//1.则判断当前节点的左子节点是否为空,如果不为空,则递归前序查找//2.如果左递归前序查找,找到节点,则返回HeroNode resNode=null;if(this.left!=null){resNode=this.left.preOrderSearch(no);}if(resNode!=null){//说明我们左子树找到return resNode;}//1.左递归前序查找,找到节点,则返回,否则判断//2.当前的节点的右子节点是否为空,如果不空,则继续向右递归前序查找if(this.right!=null){resNode=this.right.preOrderSearch(no);}return resNode;}//中序遍历查找public HeroNode infixOrderSearch(int no){//判断当前节点的左子节点是否为空,如果不为空,则递归中序查找HeroNode resNode=null;if(this.left!=null){resNode=this.left.infixOrderSearch(no);}if(resNode!=null){//说明我们左子树找到return resNode;}System.out.println("进入中序查找");//如果找到,则返回,如果没有找到,就和当前节点比较,如果是则返回当前节点if(this.no==no){return this;}//否则继续进行右递归的中序查找if(this.right!=null){resNode=this.right.infixOrderSearch(no);}return resNode;}//后序遍历查找public HeroNode postOrderSearch(int no){//判断当前节点的左子节点是否为空,如果不为空,则递归中序查找HeroNode resNode=null;if(this.left!=null){resNode=this.left.postOrderSearch(no);}if(resNode!=null){//说明我们左子树找到return resNode;}//如果左子树没有找到,则向右子树递归进行后序遍历查找if(this.right!=null){resNode=this.right.postOrderSearch(no);}if(resNode!=null){//说明我们右子树找到return resNode;}System.out.println("进入后序遍历");//如果左右子树都没有找到,就比较当前节点是不是if(this.no==no){return this;}return resNode;}}

遍历线索化二叉树+图解相关推荐

  1. Java实现前中后序线索化二叉树以及遍历

    文章目录 一.线索化二叉树的原理 二.构建线索化二叉树 三.代码实现线索二叉树 一.线索化二叉树的原理 在前面介绍二叉树的文章中提到,二叉树可以使用两种存储结构:顺序存储和链式存储,在使用链式存储时, ...

  2. 【算法系列之线索化二叉树,前序线索化、中序线索化、后序线索化以及遍历~】

    1.何谓线索化二叉树 2.线索化二叉树的本质 3.线索化二叉树的存储结构 4.构建线索化二叉树 4.1.先序线索化 4.2.中序线索化 4.3.后序线索化 5.遍历线索化二叉树 5.1.先序遍历 先序 ...

  3. 数据结构 - 线索化二叉树(线索化与遍历)

    !!(这里我debug很久才理解过来)** 这里8的前驱为null,所以8的leftType=1,但是6是没有后继的或者说后继为null但是rightType为0(因为后继是在下一个节点来进行连接的, ...

  4. 线索化二叉树及其遍历

    线索化二叉树及其遍历 线索二叉树基本介绍 1.利用二叉表中空指针域,存放指向该结点在某种遍历次序下的前驱与后续节点的指针称为线索 2.这种加上了线索的二叉链表称为线索链表,相应的二叉树也称为线索二叉树 ...

  5. 数据结构: 线索化二叉树

    public class ThreadedBinaryTreeDemo {public static void main(String[] args) {// 先创建一棵二叉树ThreadedBina ...

  6. 顺序存储二叉树和线索化二叉树

    二叉树(二) 一.顺序存储二叉树 1.1 顺序存储二叉树的概述 1.2 顺序存储的代码实现 二.线索化二叉树 2.1 线索化二叉树的概述 2.2线索化二叉树的代码实现 2.3 遍历线索化二叉树 一.顺 ...

  7. 后序线索化二叉树及遍历(图解)

    上一篇博客对于 二叉树线索化以及线索化的先序.中序.后序遍历做了比较详细的描述 写在前面 其实,我还是很想把本篇博客和二叉树的线索化写在一块的,但是考虑到可能这博客的内容就看足以超过了上一篇的篇幅,考 ...

  8. 数据结构与算法(java):树-二叉树(二叉查找树(BST)、线索化二叉树、哈夫曼树、平衡二叉树【AVL】、二叉树的前中后序遍历)

    二叉树 1.定义 二叉树 就是度不超过2的树(每个结点最多只有两个子结点).如图 2.特殊二叉树 满二叉树 当二叉树的每一个层的结点树都达到最大值,则这个二叉树就是满二叉树. 完全二叉树 叶结点只能出 ...

  9. 线索化二叉树及遍历_笔记

    线索化二叉树能够充分使用空余的left和right指针,left放前驱,right放后继指针: 一.中序线索化 1.实现思路:正常的中序思想,只不过中间实现前驱和后继节点的指向,为了确定前驱节点需要使 ...

最新文章

  1. php依赖注入 代码提示,Yii2 Day 3: 让PHPStorm支持自定义Component依赖注入代码提示
  2. 720不能建立远程计算机连接,有高手知道错误720:不能建立到远程计算机的连接这个问题怎么解决? 爱问知识人...
  3. kettle 笛卡尔_Kettle用户操作手册1
  4. python编写arcgis脚本教程_ArcGIS使用Python脚本工具
  5. Matplotlib 中文用户指南 3.6 图例指南
  6. 诗一首,程序员不仅仅只会写程序
  7. Linux/Unix IO多路复用之select网络编程(含源码)
  8. 笔记本电脑运行卡顿的真正原因和解决方案
  9. C语言 输出数组中的全部元素的三种方法
  10. 接管理器是Android上最,10 款优秀的 Android 文件管理器
  11. 总会用到的系列2:你不理财财不理你的基金定投
  12. 海思3518ev200视频录制到TF卡,关于循环覆盖存储的问题。
  13. .NET Framework各个版本(3.0 - 3.5)
  14. 如何解决中小企业融资难问题
  15. Flutter Checkbox 复选框
  16. 边界外推和边界处理--cv::copyMakeBorder()和cv::borderInterpolate()
  17. c语言和matlab的区别,Matlab与C语言区别.pdf
  18. html怎么搞一个微信图标,微信图标怎么点亮 两步搞定!
  19. css加简单的JavaScript做出毛玻璃效果
  20. 软中断指令INT 理解

热门文章

  1. word List23
  2. 如何维持手机电池寿命_延长手机电池寿命终极技巧教学,iPhone和安卓手机皆适合...
  3. Codeforces Round #601 (Div. 2) E2. Send Boxes to Alice (Hard Version) 思维 + 质因子
  4. cf1557 C. Moamen and XOR
  5. P3455 [POI2007]ZAP-Queries
  6. 2020牛客国庆集训派对day4 Emergency Evacuation
  7. 洛谷P6302:回家路线(斜率优化)
  8. P6091-[模板]原根
  9. 牛客国庆集训派对day6TJ-DefenseTower【贪心】
  10. 欢乐纪中某B组赛【2019.1.29】