二叉树前、中、后线索化及对应前、中、后序线索化遍历
二叉树前中后线索化及对应前中后序线索化遍历(图解)
二叉树线索化都是套路,会一种另外两种只是稍微修改一下代码
值得一提的是后序线索化输出,逆序思维将后序线索化看成前序,采用"前序线索化输出"代码更加简洁,也更好理解
线索化基本介绍
二叉树线索化百度百科介绍:
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 线索二叉树的构造 2.1 线索二叉树的存储结构 2.2 给线索二叉树画线索 2.2.1 中序 2.2.2 先序 2.2.3 后序 2.3 ...
- 二叉树前、中、后序线索化及遍历
public class ThreadedBinaryTree {public static void main(String[] args){Heronodes node1=new Heronode ...
- 二叉树的先序线索化、中序线索化、后序线索化的对比
有一点需要注意:在先序遍历一个节点的左子树时,需要判断其ltag的值是否为0,如果为0可以正常遍历,但是,如果为1就不能进行遍历.因为ltag的值为1说明该结点的左指针指向的是它的前驱结点而不是左孩子 ...
- 线索二叉树和中序非递归遍历线索化后的二叉树
//线索二叉树 #include<stdio.h> #include<malloc.h> #include<process.h> #define OVERFLOW ...
- Java实现前中后序线索化二叉树以及遍历
文章目录 一.线索化二叉树的原理 二.构建线索化二叉树 三.代码实现线索二叉树 一.线索化二叉树的原理 在前面介绍二叉树的文章中提到,二叉树可以使用两种存储结构:顺序存储和链式存储,在使用链式存储时, ...
- 线索二叉树原理及前序、中序线索化(Java版)
转载 原文地址:https://blog.csdn.net/UncleMing5371/article/details/54176252 一.线索二叉树原理 前面介绍二叉树原理及特殊二叉树文章中提到, ...
- 先序abdfcegh 中序bfdagehc 后序线索二叉树_二叉树的遍历和线索二叉树
二叉树的遍历是指按某条搜索路径访问树中的每个结点,使得每个结点均被访问一次,且只被访问一次. 先序遍历(NLR) 若二叉树为空,则什么也不做:否则, (1)访问根结点. (2)先序遍历左子树. (3) ...
- 二叉树前序中序后续线索树_后序线索二叉树怎么画 线索二叉树基本操作详解 - 办公软件 - 服务器之家...
后序线索二叉树怎么画 线索二叉树基本操作详解 发布时间:2017-05-23 来源:服务器之家 遍历二叉树是以一定规则将二叉树中结点排列成一个线性序列,得到二叉树中结点的先序,中序或后序序列.这实际上 ...
最新文章
- 【浅墨Unity3D Shader编程】之三 光之城堡篇:子着色器、通道与标签的写法 amp; 纹理混合...
- 概率占据图(POM)算法理解
- openglshader实现虚拟场景_opengl+shader
- 可怕的春运,烦人的火车票!
- jQuery AJAX 与 jQuery 事件
- PyTorch学习笔记——词向量简介
- Axios 请求配置参数详解
- Android之Handler,举例说明如何更新UI
- h5调用摄像头 android,H5 使用移动端摄像头
- 输入某班C语言考试成绩,人数未知,用-1作为结束标志,若大于100分,则重新输入,计算全班的最高分、最低分与平均分
- python-docx处理word文件指定页面批量打印
- HighCharts柱状图显示百分比
- 那一年岳云鹏14岁,郭德纲26岁
- 网站ssl证书出现错误如何解决
- 能量英语(三) 之 “情感把控 II ”
- This beta version of Typora is expired, please download and install a newer version
- 记一次oracle通过dblink连接mysql实施
- photoshop将图层导出到文件脚本不带数字序号、下划线方法
- nginx缓冲区链表chain
- CSMA/CD 协议 详解
热门文章
- Datawhale-数据挖掘实践(智慧海洋)
- 怎样使用七牛云CDN加速并绑定阿里云域名
- Spring-ICE 结冰算法述评-(5)对流换热系数计算
- 名悦集团在线盘点汽车品牌标志背后的那些故事
- 最新升级pip命令,查看pip版本命令,pycharm升级pip命令,推荐收藏关注不迷路
- 基于51单片机的水温可测液体温度的控制器设计
- 虹膜识别论文1:Iris Recognition With Off-the-Shelf CNN Features: A Deep Learning Perspective 2017年 学习心得
- 【图片新闻】俄罗斯新型“Okhotnik”(“猎人”)重型攻击无人机首次亮相
- 安拆网分享:脚手架的防火要求及措施
- DNG图像文件的解码