线索化二叉树能够充分使用空余的left和right指针,left放前驱,right放后继指针;
一、中序线索化
1、实现思路:正常的中序思想,只不过中间实现前驱和后继节点的指向,为了确定前驱节点需要使用一个preNode来记录上一个处理的节点,当前节点left为空时,让其指向preNode,这样前驱节点确定;要确定后继节点就要知道当前节点的下一个节点是什么,所以直接使用preNode来处理上个节点的后继节点,也就是在当前节点来处理上一个节点的后继节点。不过这样的话,最后一个节点的后继节点就没法处理了,可以通过重载将其设置。
这样完成之后,在遍历的时候会出现问题,陷入死循环,因此需要加一个leftType标志和rightType标志,来确定一个节点的左右节点是左右子树还是前驱后继节点,所以在处理前驱后继的时候就需要同时把这两个type进行处理。
2、中序遍历
实现思路:在进行遍历的时候,由于加入了前驱和后继节点所以可能出现死循环(明明只要加上判断leftType==0和rightType等于0为真时才进入递归就好了,不知道为什么要这么麻烦,感觉可能是为了把线索化的前驱和后继节点用上吧),因此要使用新的遍历方法,那就是结合前驱和后继节点进行遍历。主要思路就是先找到最左叶子节点(通过leftType进行判断)然后通过一个while循环进行处理:当前节点有后继节点的话,node=node.right,指向后继节点,如果没有后继节点的话,node=node.right指向右子节点,并且循环找到最左叶子节点;
也可以倒序输出,也就是利用前驱节点进行输出;主要思路:先找到最右子节点(需要在线索化的时候处理最后一个子节点的rightType),然后循环:如果是有前驱节点的,node=node.left;如果是没有前驱节点的,先node=node.left然后循环找到这个节点的最右子节点;
3、后序遍历
实现思路:后序遍历由于是左右根,先找到最左子节点,开始循环:如果有后继节点,node=node.left,若果没有后继节点node=node.parent(后序遍历专用的,用来记录父节点),这时会发现可能会出现问题:如果对每一个没有后继节点的节点都这样处理的话,有的节点的右子树就会被遗漏;观察发现如果当前节点的右子节点是上一个处理的节点的话,是可以直接node=node.parent的,否则需要先node=node.right然后循环找到最左子节点;

//中序线索化
void infixThreadTree(Node1 node) {if (node == null) {return;}infixThreadTree(node.left);//线索化leftif (node.left == null) {node.left = pre;node.leftType = 1;}//线索化前置节点的rightif (pre != null && pre.right == null) {pre.right = node;pre.rightType = 1;}pre = node;infixThreadTree(node.right);}//中序线索化遍历(使用后继节点)void infixTraverseTreeByAfter() {Node1 node = root;while (node != null && node.leftType == 0) {node = node.left;}while (node != null) {if (node.rightType == 1) {System.out.println(node.id);node = node.right;} else {System.out.println(node.id);node = node.right;while (node != null && node.leftType == 0) {node = node.left;}}}}//中序线索化遍历(使用前驱节点,倒序输出)void infixTraverseTreeByPre() {Node1 node = root;while (node != null && node.rightType == 0) {node = node.right;}while (node != null) {System.out.println(node.id);if (node.leftType == 1) {node = node.left;} else {node = node.left;while (node != null && node.rightType == 0) {node = node.right;}}}}//后序遍历public void postTraverseTree() {//1、找后序遍历方式开始的节点Node1 node = root;while (node != null && node.leftType == 0) {node = node.left;}while (node != null) {//右节点是线索if (node.rightType == 1) {System.out.print(node.id + ", ");pre = node;node = node.right;} else {//如果上个处理的节点是当前节点的右节点if (node.right == pre) {System.out.print(node.id + ", ");if (node == root) {return;}pre = node;node = node.parent;} else {    //如果从左节点的进入则找到有子树的最左节点node = node.right;while (node != null && node.leftType == 0) {node = node.left;}}}}}

线索化二叉树及遍历_笔记相关推荐

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

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

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

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

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

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

  4. Java:中序线索化二叉树及遍历

    class Threade{BinaryTree root;//记录根节点,用于遍历BinaryTree pre;//pre指针,用于线索化,表示上一个节点Threade(BinaryTree nod ...

  5. 线索化二叉树,中序建立线索,带线索中序遍历,删除,c/c++描述

      二叉树的叶节点的两个指针都没有利用,一些分支节点也可能有一个指针指向NULL,这些指针造成了程序在内存空间上的浪费,但这些叶节点也必不可省.所以我们可以把这些指向NULL的指针,重新赋值,左指针则 ...

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

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

  7. 遍历线索化二叉树+图解

    图解 代码实现 package com.atguigu.tree.threadedbinarytree;/*** @创建人 wdl* @创建时间 2021/3/25* @描述*/ public cla ...

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

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

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

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

最新文章

  1. org.hibernate.hibernate.connection.release_mode
  2. eclipse扩展点_Eclipse扩展点评估变得容易
  3. pg插入执行成功但是没有数据_pg_lightool基于basebackup的单表恢复和块恢复
  4. mysql mvcc gap lock_为什么说 MVCC 和 Gap Lock 解决了 MySQL 的幻读问题
  5. confluence 统计页面访问量插件Page View Tracker
  6. OpenCV精进之路(零):HighGUI——读写XML和YML文件
  7. 数据呈现—ListView x Adapter
  8. xml 标签带有号php,php截取字符串并保留完整xml标签的函数代码
  9. python 终止程序代码 多线程_我想问一下,tkinter 做多线程爬虫,让他停止该怎么做 quit 和 exit 都是直接退出程序...
  10. matlab理论力学项目研究,基于MATLAB的机械力学问题的研究
  11. 广州IT销售菜鸟总结精华
  12. PCI Expansion ROMs
  13. java中的radix_int radix()
  14. 高项47个过程及输入、输出、工具解释
  15. 学习突围3 - 关于精力
  16. R语言绘制坐标 保存图片
  17. java操作excel方法_Java实现操作excel表格的方法
  18. WinX菜单是Win8系统开始菜单的下一代
  19. 跨国企业在中国 | 洲际新签15家特许经营模式酒店;爱马仕中国第26家卖店在厦门揭幕...
  20. awk命令详解(大全)

热门文章

  1. 隐藏域 HiddenField
  2. 还记得蜘蛛纸牌吗?这个C++开发的小游戏,原来是这样玩的
  3. 火狐浏览器title显示不全
  4. ANDROID 开源书架
  5. 仅剩一天,驾校迎新规,驾驶模拟器新国标有变!
  6. try catch真的会影响性能?居然被骗了好几年...
  7. c语言课程设计礼花的绽放,计算机技术基础(c语言)课程设计 制作节日礼花.doc
  8. 剪切的文件怎么恢复?
  9. Unity-3D捕鱼达人小游戏开发 —— 游戏中场景
  10. 闲谈GIS专业导向与个人定位问题