二叉树前中后线索化及对应前中后序线索化遍历(图解)

二叉树线索化都是套路,会一种另外两种只是稍微修改一下代码

值得一提的是后序线索化输出,逆序思维将后序线索化看成前序,采用"前序线索化输出"代码更加简洁,也更好理解

线索化基本介绍

二叉树线索化百度百科介绍:
https://baike.baidu.com/item/%E7%BA%BF%E7%B4%A2%E4%BA%8C%E5%8F%89%E6%A0%91/10810037?fr=aladdin

以下面二叉树为例

前序化流程图解

创建节点对象 (使用数组更方便)

class TreeNode1 {private int no;private TreeNode1 left;private TreeNode1 right;/** 说明: 1.如果 letfType 或 rightType 为 0 表示 左子树或右子树 2.如果 letfType 或 rightType 为 1 表示* 前驱或后驱节点*/private int leftType;private int rightType;public TreeNode1(int no) {this.no = no;}//getter/setter ...@Overridepublic String toString() {return "TreeNode1 [no=" + no + "]";}}

创建一个类实现线索化

class TreeManger1 {private TreeNode1 root;public void setRoot(TreeNode1 root) {this.root = root;}...线索化
}

## 中序最简单也最容易理解 所以先看一下中序线索化

// 为了实现 线索化,需要创建一个变量,指定向前节点的前驱节点// 在递归进行索化时,infixPre 总是保留前一个节点TreeNode1 infixPre = null;public void infixThreadTreeNode() {this.infixThreadTreeNode(root);}// 中序线索化public void infixThreadTreeNode(TreeNode1 node) {// 如果 node == null 则不能索化if (node == null) {return;}// 1.线索化左子树infixThreadTreeNode(node.getLeft());// 2.线索化当前节点if (node.getLeft() == null) {// 让当前节点的左指针指向前驱节点node.setLeft(infixPre);// 修改当前节点的左指针的类型,指向前驱节点node.setLeftType(1);}// 处理后继节点         if (infixPre != null && infixPre.getRight() == null) {// 让前驱节点的有指针指向当前节点infixPre.setRight(node);// 修改前驱节点的右指针类型infixPre.setRightType(1);}// !!!!!没处理一个节点后让当前节点指向下一个节点的前驱节点infixPre = node;// 3.线索化右子树infixThreadTreeNode(node.getRight());}

中序线索化遍历

// 中序线索化输出public void infixThreadTreeNodeOrde() {// 定义一个节点存储当前遍历的节点 从 root 开始TreeNode1 node = root; while (node != null) {// 循环找到 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();}}

前序线索化

TreeNode1 prePre = null;// 前序线索化public void preThread(TreeNode1 node) {if (node == null) {return;}// 线索化当前节点if (node.getLeft() == null) {node.setLeft(prePre);node.setLeftType(1);}if (prePre != null && prePre.getRight() == null) {prePre.setRight(node);prePre.setRightType(1);}prePre = node;// 线索化左子树if (node.getLeftType() != 1) {preThread(node.getLeft());}// 线索化右子树if (node.getRightType() != 1) {preThread(node.getRight());}}

前序线索化输出

// 前序索化输出public void preThreadOrder() {TreeNode1 node = root;while (node != null) {while (node.getLeftType() != 1) {System.out.println(node);node = node.getLeft();}System.out.println(node);node = node.getRight();}}

后序线索化

TreeNode1 postPre = null;// 后序序线索化public void postThread(TreeNode1 node) {if (node == null) {return;}// 线索化左子树postThread(node.getLeft());// 线索化右子树postThread(node.getRight());// 线索化当前节点if (node.getLeft() == null) {node.setLeft(postPre);node.setLeftType(1);}if (postPre != null && postPre.getRight() == null) {postPre.setRight(node);postPre.setRightType(1);}postPre = node;}

后序线索化输出

/** 后线索化输出* * 逆序前线索化,将其压入栈中,最后依次弹出即可* */public void postThreadOrde() {Stack<TreeNode1> stack = new Stack<TreeNode1>();TreeNode1 node = root;while (node != null) {while (node.getRightType() != 1) {stack.push(node);node = node.getRight();}stack.push(node);node = node.getLeft();}while (!stack.isEmpty()) {System.out.println(stack.pop());}}

一张图对比一下 其实都是套路

全部代码

package com.kc.c09_tree._02threadbinarytree;import java.util.ArrayList;
import java.util.List;
import java.util.Stack;public class T {public static void main(String[] args) {TreeNode1 n11 = new TreeNode1(11);TreeNode1 n21 = new TreeNode1(21);TreeNode1 n31 = new TreeNode1(31);TreeNode1 n14 = new TreeNode1(14);TreeNode1 n15 = new TreeNode1(15);TreeNode1 n61 = new TreeNode1(61);TreeNode1 n71 = new TreeNode1(71);TreeNode1 n81 = new TreeNode1(81);TreeNode1 n91 = new TreeNode1(91);n11.setLeft(n21);n11.setRight(n31);n21.setLeft(n14);n21.setRight(n15);n31.setLeft(n61);n31.setRight(n71);n14.setLeft(n81);n14.setRight(n91);TreeManger1 tm = new TreeManger1();tm.setRoot(n11);//        tm.preThread(n11);
//      tm.infixThreadTreeNode(n11);tm.postThread(n11);
//      // 检验TreeNode1 left11 = n11.getLeft();TreeNode1 right11 = n11.getRight();System.out.println("no11 : left = " + left11 + ",right = " + right11);TreeNode1 left21 = n21.getLeft();TreeNode1 right21 = n21.getRight();System.out.println("no21 : left = " + left21 + ",right = " + right21);TreeNode1 left31 = n31.getLeft();TreeNode1 right31 = n31.getRight();System.out.println("no31 : left = " + left31 + ",right = " + right31);TreeNode1 left14 = n14.getLeft();TreeNode1 right14 = n14.getRight();System.out.println("no14 : left = " + left14 + ",right = " + right14);TreeNode1 left81 = n81.getLeft();TreeNode1 right81 = n81.getRight();System.out.println("no81 : left = " + left81 + ",right = " + right81);TreeNode1 left91 = n91.getLeft();TreeNode1 right91 = n91.getRight();System.out.println("no91 : left = " + left91 + ",right = " + right91);TreeNode1 left15 = n15.getLeft();TreeNode1 right15 = n15.getRight();System.out.println("no15 : left = " + left15 + ",right = " + right15);TreeNode1 left61 = n61.getLeft();TreeNode1 right61 = n61.getRight();System.out.println("no61 : left = " + left61 + ",right = " + right61);TreeNode1 left71 = n71.getLeft();TreeNode1 right71 = n71.getRight();System.out.println("no71 : left = " + left71 + ",right = " + right71);//        tm.preThreadOrder();
//      tm.infixThreadTreeNodeOrde();tm.postThreadOrde();}
}class TreeManger1 {private TreeNode1 root;public void setRoot(TreeNode1 root) {this.root = root;}/********* 线索化二叉树 *********//******************************************/TreeNode1 prePre = null;// 前序线索化public void preThread(TreeNode1 node) {if (node == null) {return;}// 线索化当前节点if (node.getLeft() == null) {node.setLeft(prePre);node.setLeftType(1);}if (prePre != null && prePre.getRight() == null) {prePre.setRight(node);prePre.setRightType(1);}prePre = node;// 线索化左子树if (node.getLeftType() != 1) {preThread(node.getLeft());}// 线索化右子树if (node.getRightType() != 1) {preThread(node.getRight());}}// 前序索化输出public void preThreadOrder() {TreeNode1 node = root;while (node != null) {while (node.getLeftType() != 1) {System.out.println(node);node = node.getLeft();}System.out.println(node);node = node.getRight();}}/******************************************/TreeNode1 postPre = null;// 后序序线索化public void postThread(TreeNode1 node) {if (node == null) {return;}// 线索化左子树postThread(node.getLeft());// 线索化右子树postThread(node.getRight());// 线索化当前节点if (node.getLeft() == null) {node.setLeft(postPre);node.setLeftType(1);}if (postPre != null && postPre.getRight() == null) {postPre.setRight(node);postPre.setRightType(1);}postPre = node;}/** 后线索化输出* * 逆序前线索化,将其压入栈中,最后依次弹出即可* */public void postThreadOrde() {Stack<TreeNode1> stack = new Stack<TreeNode1>();TreeNode1 node = root;while (node != null) {while (node.getRightType() != 1) {stack.push(node);node = node.getRight();}stack.push(node);node = node.getLeft();}while (!stack.isEmpty()) {System.out.println(stack.pop());}}/*************************************/// 为了实现 线索化,需要创建一个变量,指定向前节点的前驱节点// 在递归进行索化时,infixPre 总是保留前一个节点TreeNode1 infixPre = null;public void infixThreadTreeNode() {this.infixThreadTreeNode(root);}// 中序线索化public void infixThreadTreeNode(TreeNode1 node) {// 如果 node == null 则不能索化if (node == null) {return;}// 1.线索化左子树infixThreadTreeNode(node.getLeft());// 2.线索化当前节点if (node.getLeft() == null) {// 让当前节点的左指针指向前驱节点node.setLeft(infixPre);// 修改当前节点的左指针的类型,指向前驱节点node.setLeftType(1);}// 处理后继节点if (infixPre != null && infixPre.getRight() == null) {// 让前驱节点的有指针指向当前节点infixPre.setRight(node);// 修改前驱节点的右指针类型infixPre.setRightType(1);}// !!!!!没处理一个节点后让当前节点指向下一个节点的前驱节点infixPre = node;// 3.线索化右子树infixThreadTreeNode(node.getRight());}// 中序线索化输出public void infixThreadTreeNodeOrde() {// 定义一个节点存储当前遍历的节点 从 root 开始TreeNode1 node = root;while (node != null) {// 循环找到 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();}}}class TreeNode1 {private int no;private TreeNode1 left;private TreeNode1 right;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 TreeNode1(int no) {this.no = no;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public TreeNode1 getLeft() {return left;}public void setLeft(TreeNode1 left) {this.left = left;}public TreeNode1 getRight() {return right;}public void setRight(TreeNode1 right) {this.right = right;}@Overridepublic String toString() {return "TreeNode1 [no=" + no + "]";}}

二叉树前、中、后线索化及对应前、中、后序线索化遍历相关推荐

  1. 为什么先序/中序线索二叉树不需要栈的支持,而后序线索二叉树需要栈的支持?

    为什么先序/中序线索二叉树不需要栈的支持,而后序线索二叉树需要栈的支持? 首先要明确两点 先序线索二叉树的缺点:无法找到先序序列中某结点的前驱 后序线索二叉树的缺点:无法找到后序序列中某结点的后继 中 ...

  2. 线索二叉树(前中后序线索化/遍历/画线索)

    线索二叉树 文章目录 线索二叉树 1 线索二叉树的基本概念 2 线索二叉树的构造 2.1 线索二叉树的存储结构 2.2 给线索二叉树画线索 2.2.1 中序 2.2.2 先序 2.2.3 后序 2.3 ...

  3. 二叉树前、中、后序线索化及遍历

    public class ThreadedBinaryTree {public static void main(String[] args){Heronodes node1=new Heronode ...

  4. 二叉树的先序线索化、中序线索化、后序线索化的对比

    有一点需要注意:在先序遍历一个节点的左子树时,需要判断其ltag的值是否为0,如果为0可以正常遍历,但是,如果为1就不能进行遍历.因为ltag的值为1说明该结点的左指针指向的是它的前驱结点而不是左孩子 ...

  5. 线索二叉树和中序非递归遍历线索化后的二叉树

    //线索二叉树 #include<stdio.h> #include<malloc.h> #include<process.h> #define OVERFLOW ...

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

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

  7. 线索二叉树原理及前序、中序线索化(Java版)

    转载 原文地址:https://blog.csdn.net/UncleMing5371/article/details/54176252 一.线索二叉树原理 前面介绍二叉树原理及特殊二叉树文章中提到, ...

  8. 先序abdfcegh 中序bfdagehc 后序线索二叉树_二叉树的遍历和线索二叉树

    二叉树的遍历是指按某条搜索路径访问树中的每个结点,使得每个结点均被访问一次,且只被访问一次. 先序遍历(NLR) 若二叉树为空,则什么也不做:否则, (1)访问根结点. (2)先序遍历左子树. (3) ...

  9. 二叉树前序中序后续线索树_后序线索二叉树怎么画 线索二叉树基本操作详解 - 办公软件 - 服务器之家...

    后序线索二叉树怎么画 线索二叉树基本操作详解 发布时间:2017-05-23 来源:服务器之家 遍历二叉树是以一定规则将二叉树中结点排列成一个线性序列,得到二叉树中结点的先序,中序或后序序列.这实际上 ...

最新文章

  1. 卓京计算机学校,卓京--计算机数据原理课程设计任务书.doc
  2. 类库,通用变量,is/as运算符,委托。
  3. 爬虫实战:CentOS安装JDK,部署Java程序,利用screen使其保持在前台运行
  4. python语法详解_解析 Python3 基础语法
  5. 关于高效企业测试的思考(1/6)
  6. (pytorch-深度学习系列)使用重复元素的网络(VGG)
  7. 设置linux文件系统密码,busybox 文件系统设置 登陆 login 密码 password shadow
  8. [Android]Notification汇总
  9. 新股上市涨跌幅规则?
  10. 从天天爱消除和节奏大师的用户对于论坛形式的分析
  11. Python爬虫开发【第1篇】【urllib2】
  12. Email - 搭建自定义邮件服务器
  13. c语言case后语句,switch语句中case后的标号是什么
  14. Python 字符串 .format 方法详解
  15. 移动端怎么让图片不失真_图片怎样放大后不模糊 图片放大不失真的方法步骤...
  16. RSA之共模攻击与共享素数
  17. 【数字图像处理】图像滤波C语言实现(中值,均值,高斯)
  18. CSDN-JayChou测试
  19. 永远不怕IE主页地址被修改
  20. poj 1066 Treasure Hunt

热门文章

  1. ibm 还销售服务器吗,IBM卖掉x86服务器,低端存储业务会被放弃吗?
  2. 23本科毕业一年,从事C语言单片机工作一年半了,我都不知道以后干嘛了
  3. cocos2d-x 使用tmx地图总结
  4. java poi 创建电子表格
  5. 转行数据科学路上的点点滴滴
  6. 解决:JDK安装下一步没反应,JDK安装失败
  7. jupyter设置中/英文语言
  8. 基于深度学习GPU+FPGA 多路高清视频处理模块
  9. 提取微信公众平台模板消息字段
  10. cpu_freq之切换governor.