图解

代码实现

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. R语言基于DALEX包进行特征筛选(feature selection)
  2. [TCP/IP] TCP如何实现流量控制和拥塞控制
  3. JS实现大整数乘法(性能优化、正负整数)
  4. java progressbar swt_SWT(JFace)体验之ProgressBar
  5. Android中调用系统所装的软件打开文件,android应用开发基础学堂在线答案
  6. 云服务器obs_从零搭建流媒体服务器+obs推流直播
  7. 武汉大学计算机学院期末考试安排,【通知】关于2019-2020学年第一学期期末考试工作安排的通知...
  8. 四川职业技术学院linux,2019年四川交通职业技术学院单招中职(信息技术一类)专业技能测试大纲...
  9. 区块链打造“红娘链”,婚姻上链让爱更“牢固”
  10. mysql和python先学哪个_Python之路-python(mysql介绍和安装、pymysql、ORM sqlachemy)
  11. 36页智慧安防小区管控系统解决方案
  12. 【前后端对接迷惑问题】无法加载响应数据:No resource with given identifier found
  13. Cobbler自动化部署
  14. Unity用代码批量修复材质球shader丢失的问题
  15. FAR planner浅尝试
  16. 步进电机+protues
  17. 2020最新微信棋牌游戏H5域名防封的解决方案
  18. 基础练习21- Sine之舞(python答案)
  19. LSC(Lens Shading Correction)——镜头阴影矫正
  20. 有没有测试硬盘的软件,检测硬盘有什么好软件

热门文章

  1. github 检查代码质量_Android(8): 代码质量检查
  2. laravel 模板继承_Laravel框架模板之公共模板、继承、包含实现方法分析
  3. LeetCode动态规划 斐波那契数
  4. Java开发Web Service的简介
  5. MySQL集群搭建——主备模式
  6. Legacy(线段树优化建边跑Dijkstra)
  7. #3027. [Ceoi2004]Sweet 生成函数 + 组合数学
  8. Codeforces Round #635 (Div. 1) C. Kaavi and Magic Spell 区间dp
  9. Codeforces Round #701 (Div. 2) D. Multiples and Power Differences 思维构造
  10. 【省选2020A卷】作业题【矩阵树】【扩域】【莫比乌斯反演】