线索二叉树 矫情吗;* 2021-10-01 09:34 372阅读 0赞 # Overview # 将二叉树中没有子节点的节点称为空指针域,利用二叉树的空指针域,按照前中后某种遍历方式存放对应的前驱节点,后驱节点(这种附加指针称为“线索”)。二叉树的空指针域存储对应前后驱节点的二叉树叫做线索二叉树。(他的空指针域存放着他的前一个后一个节点的信息)。 ![18721752-c8529e8d41a55ad9.png][] image.png # 特点: # 在线索二叉树中,left可以指向左子树,也可能是指向前驱节点。(因为只有空指针域才能线索化,所以lefth或者right只能同时存在一种情况,要么指向左右树,要么指向前后驱节点)。 right指向右子树,也可能指向后驱节点。 # 空指针域的计算公式 # ![18721752-602cdbb2937da36a.png][] image.png # code # ThreadBinaryTree package com.pl.arithmetic.binaryTree.threadBinaryTree; import lombok.Data; import lombok.NoArgsConstructor; /** * <p> * * @Description: 中序线索二叉树 * </p> * @ClassName ThreadBinaryTree * @Author pl * @Date 2020/11/7 * @Version V1.0.0 */ @Data @NoArgsConstructor public class ThreadBinaryTree { private ThreadHeroNode root; //前驱节点临时变量 中序遍历第一个节点的前驱节点必为空 private ThreadHeroNode preTempVal = null; public ThreadBinaryTree(ThreadHeroNode root) { this.root = root; } //重载一把threadedNodes方法 public void buildThreadedNodes() { this.buildThreadedNodes(root); } /** * 按照中序遍历 线索化二叉树 * 因为二叉树节点遍历都是单向的,无法知道其前后节点,所以通过过程变量存储当前节点,作为后一个节点的前驱节点,遍历到后续节点时候再为前驱节点赋值后驱节点 * * @param node * @return void * @exception * @author silenter * @date 2020/11/7 22:13 */ public void buildThreadedNodes(ThreadHeroNode node){ if (node == null){ System.out.println("不能线索化空节点"); return; } //中序遍历线索二叉树 按照中序遍历顺序来构建线索二叉树 先线索化左节点 在线索化当前节点 后线索化右节点 //@1 线索化左子树 buildThreadedNodes(node.leftNode); //因为中序遍历是单向的,当前节点是拿不到他的后一顺序的节点,所以用临时变量存储当前节点作为遍历顺序中,下一个节点的前驱节点。 //当前节点如果是能够线索化的节点,那么只能赋值他的前驱节点,线索化其后驱节点,只能将当前节点存储在前驱临时变量中,让后一个节点为他补齐他的后驱节点。 //@2 线索化当前节点 if (node.leftNode == null){ node.leftNode = preTempVal; node.leftTreadType=1; } if (preTempVal!=null && preTempVal.rightNode == null){ preTempVal.rightNode = node; preTempVal.rightTreadType = 1; } //当前节点左右节点线索化逻辑执行之后将当前节点存储到临时变量中,作为后一个节点的前驱节点。 preTempVal = node; //线索化右子树 buildThreadedNodes(node.rightNode); } } ThreadHeroNode package com.pl.arithmetic.binaryTree.threadBinaryTree; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Objects; /** * <p> * * @Description: TODO * </p> * @ClassName ThreadHeroNode * @Author pl * @Date 2020/11/7 * @Version V1.0.0 */ @Data @NoArgsConstructor @AllArgsConstructor public class ThreadHeroNode { int value; String name; ThreadHeroNode leftNode; ThreadHeroNode rightNode; //是否线索化标记 //1. 如果leftType == 0 表示指向的是左子树, 如果 1 则表示指向前驱结点 //2. 如果rightType == 0 表示指向是右子树, 如果 1表示指向后继结点 int leftTreadType; int rightTreadType; public ThreadHeroNode(int value, String name) { this.value = value; this.name = name; } @Override public String toString() { return "ThreadHeroNode{" + "value=" + value + ", name='" + name + '\'' + '}'; } } TestDemo package com.pl.arithmetic.binaryTree.threadBinaryTree; /** * <p> * * @Description: TODO * </p> * @ClassName TestDemo * @Author pl * @Date 2020/10/20 * @Version V1.0.0 */ public class TestDemo { public static void main(String[] args) { //测试一把中序线索二叉树的功能 ThreadHeroNode root = new ThreadHeroNode(1, "tom"); ThreadHeroNode node2 = new ThreadHeroNode(3, "jack"); ThreadHeroNode node3 = new ThreadHeroNode(6, "smith"); ThreadHeroNode node4 = new ThreadHeroNode(8, "mary"); ThreadHeroNode node5 = new ThreadHeroNode(10, "king"); ThreadHeroNode node6 = new ThreadHeroNode(14, "dim"); //二叉树,后面我们要递归创建, 现在简单处理使用手动创建 root.setLeftNode(node2); root.setRightNode(node3); node2.setLeftNode(node4); node2.setRightNode(node5); node3.setLeftNode(node6); //测试中序线索化 ThreadBinaryTree threadedBinaryTree = new ThreadBinaryTree(root); threadedBinaryTree.buildThreadedNodes(); //测试: 以10号节点测试 ThreadHeroNode leftNode = node5.getLeftNode(); ThreadHeroNode rightNode = node5.getRightNode(); System.out.println("10号结点的前驱结点是 =" + leftNode); //3 System.out.println("10号结点的后继结点是=" + rightNode); //1 } } ![18721752-5545049fa5028d0f.png][] image.png # 遍历中序线索化二叉树 # ![18721752-59d985c6d4df4922.png][] image.png code ThreadBinaryTree package com.pl.arithmetic.binaryTree.threadBinaryTree; import lombok.Data; import lombok.NoArgsConstructor; /** * <p> * * @Description: 中序线索二叉树 * </p> * @ClassName ThreadBinaryTree * @Author pl * @Date 2020/11/7 * @Version V1.0.0 */ @Data @NoArgsConstructor public class ThreadBinaryTree { private ThreadHeroNode root; //前驱节点临时变量 中序遍历第一个节点的前驱节点必为空 private ThreadHeroNode preTempVal = null; public ThreadBinaryTree(ThreadHeroNode root) { this.root = root; } //重载一把threadedNodes方法 public void buildThreadedNodes() { this.buildThreadedNodes(root); } /** * 按照中序遍历 线索化二叉树 * * @param node * @return void * @exception * @author silenter * @date 2020/11/7 22:13 */ public void buildThreadedNodes(ThreadHeroNode node){ if (node == null){ System.out.println("不能线索化空节点"); return; } //中序遍历线索二叉树 按照中序遍历顺序来构建线索二叉树 先线索化左节点 在线索化当前节点 后线索化右节点 //@1 线索化左子树 buildThreadedNodes(node.leftNode); //因为中序遍历是单向的,当前节点是拿不到他的后一顺序的节点,所以用临时变量存储当前节点作为遍历顺序中,下一个节点的前驱节点。 //当前节点如果是能够线索化的节点,那么只能赋值他的前驱节点,线索化其后驱节点,只能将当前节点存储在前驱临时变量中,让后一个节点为他补齐他的后驱节点。 //@2 线索化当前节点 if (node.leftNode == null){ node.leftNode = preTempVal; node.leftTreadType=1; } if (preTempVal!=null && preTempVal.rightNode == null){ preTempVal.rightNode = node; preTempVal.rightTreadType = 1; } //当前节点左右节点线索化逻辑执行之后将当前节点存储到临时变量中,作为后一个节点的前驱节点。 preTempVal = node; //线索化右子树 buildThreadedNodes(node.rightNode); } /** * 遍历中序线索化二叉树,输出顺序和原有中序遍历顺序相同 * * @param * @return void * @exception * @author silenter * @date 2020/11/9 20:51 */ public void infixOrder(){ ThreadHeroNode tempNode = root; while (tempNode!=null){ //查找起始节点,起始线索化节点 while (tempNode.leftTreadType == 0){ tempNode = tempNode.leftNode; } System.out.println(tempNode); //如果右节点一直都是线索化节点,则一直输出 while (tempNode.rightTreadType ==1){ tempNode = tempNode.rightNode; System.out.println(tempNode); } //如果当前节点不是线索化节点,则将其右节点替换当前节点 tempNode = tempNode.rightNode; } } } TestDemo package com.pl.arithmetic.binaryTree.threadBinaryTree; /** * <p> * * @Description: TODO * </p> * @ClassName TestDemo * @Author pl * @Date 2020/10/20 * @Version V1.0.0 */ public class TestDemo { public static void main(String[] args) { //测试一把中序线索二叉树的功能 ThreadHeroNode root = new ThreadHeroNode(1, "tom"); ThreadHeroNode node2 = new ThreadHeroNode(3, "jack"); ThreadHeroNode node3 = new ThreadHeroNode(6, "smith"); ThreadHeroNode node4 = new ThreadHeroNode(8, "mary"); ThreadHeroNode node5 = new ThreadHeroNode(10, "king"); ThreadHeroNode node6 = new ThreadHeroNode(14, "dim"); //二叉树,后面我们要递归创建, 现在简单处理使用手动创建 root.setLeftNode(node2); root.setRightNode(node3); node2.setLeftNode(node4); node2.setRightNode(node5); node3.setLeftNode(node6); //测试中序线索化 ThreadBinaryTree threadedBinaryTree = new ThreadBinaryTree(root); threadedBinaryTree.buildThreadedNodes(); //测试: 以10号节点测试 ThreadHeroNode leftNode = node5.getLeftNode(); ThreadHeroNode rightNode = node5.getRightNode(); System.out.println("10号结点的前驱结点是 =" + leftNode); //3 System.out.println("10号结点的后继结点是=" + rightNode); //1 threadedBinaryTree.infixOrder(); } } 输出 ![18721752-b1245a6294a48e0c.png][] image.png [18721752-c8529e8d41a55ad9.png]: /images/20210918/ca3ff2e90a4c4e40a9f45e2ddeb6164e.png [18721752-602cdbb2937da36a.png]: /images/20210918/3f05da467f87468685aa39e6a97df00d.png [18721752-5545049fa5028d0f.png]: /images/20210918/444a64c52e6d4ae387862f5ce3fe9ea5.png [18721752-59d985c6d4df4922.png]: /images/20210918/076f0a5e97564b619f5e0990755d505a.png [18721752-b1245a6294a48e0c.png]: /images/20210918/5627259be0314cf180cc749dccff9233.png
相关 树——二叉树——线索二叉树 一、线索二叉树 (1)什么是线索化 将二叉树以某种次序将其遍历, 得到线性序列, 就是将非线性结构进行线索化。 线索化的优点就是可以很快地得到前驱或后继。 如 梦里梦外;/ 2023年06月13日 09:35/ 0 赞/ 13 阅读
相关 线索二叉树 一 概述 遍历二叉树是以一定的规则将二叉树中的结点排列成一个线性序列,从而得到几种遍历序列,使得该序列中的每个结点(第一个和最后一个结点除外)都有一个直接前驱和直接后继。 ﹏ヽ暗。殇╰゛Y/ 2022年12月09日 02:46/ 0 赞/ 10 阅读
相关 线索二叉树 1.基本概念 对于某些二叉树而言,其指针域的空间不能被充分利用。因此我们可以考虑利用那些空的指针域来存放指向结点在某种遍历次序下的前驱和后继结点的地址。我们把这种指向前 怼烎@/ 2022年06月14日 03:48/ 0 赞/ 188 阅读
相关 线索二叉树 线索化二叉树相对于之前的树的遍历,在树的定义上增加了两个值,一个是ltag,另外一个是rtag。 ltag代表着这个节点的是否有右孩子,如果有,则ltag=1,p->lchi 以你之姓@/ 2022年06月09日 01:13/ 0 赞/ 217 阅读
相关 线索二叉树 二叉树的链式存储如下图, ![Image 1][] 不难发现,图中所示的左—右指针表示中,有一半以上的指针是空的。事实上,所有包括n个结点的二叉树的这种表示中,每个结 秒速五厘米/ 2022年05月29日 00:18/ 0 赞/ 184 阅读
相关 线索二叉树 线索二叉树提出的原因: 在普通二叉树中,每个结点都有左右两个指针域,这些指针域都指向结点类型的数据对象,当二叉树稀疏时,很多结点的左右两个指针域就显得浪费存储空间了。因此,提 待我称王封你为后i/ 2022年03月15日 13:24/ 0 赞/ 276 阅读
相关 线索二叉树 本文主要介绍线索二叉树和树、二叉树、森林三者之间的相互转换。 对于线索二叉树,这里只做简单介绍,着重还是要理解上篇博文中二叉树的各种遍历算法。 线索二叉树 基本概念 旧城等待,/ 2022年02月23日 08:36/ 0 赞/ 249 阅读
相关 线索二叉树 什么是线索二叉树? 遍历二叉树是以一定的规则将二叉树中的结点排列成一个线性序列,从而等到二叉树的各种遍历序列,其实质是对一个非线性操作进行线性化操作,使这个访问序列中的每 女爷i/ 2022年01月23日 08:15/ 0 赞/ 277 阅读
相关 线索二叉树 package com.tree; import java.util.concurrent.SynchronousQueue; / 红太狼/ 2021年10月15日 02:37/ 0 赞/ 327 阅读
相关 线索二叉树 Overview 将二叉树中没有子节点的节点称为空指针域,利用二叉树的空指针域,按照前中后某种遍历方式存放对应的前驱节点,后驱节点(这种附加指针称为“线索”)。二叉树的空 矫情吗;*/ 2021年10月01日 09:34/ 0 赞/ 373 阅读
还没有评论,来说两句吧...