文章目录

  • 一、什么是线索二叉树(TBT)?
  • 二、线索二叉树的建立
  • 三、线索二叉树的实现

一、什么是线索二叉树(TBT)?

线索二叉树是一种优化的二叉树结构,对于以结构体指针实现二叉树的方案进行了顺序遍历的优化。

常见的使用结构体指针构建二叉树的方式如图所示:

我们知道,在使用结构体指针构建二叉树时,由于二叉树不满,会产生大量没有意义的指针,事实上即使二叉树为满二叉树,其叶子节点的左子与右子指针也为空。面对数据范围巨大的要求,过多指针的浪费是非常危险的,但是这种情况是结构体指针方案所难以避免的,而我们使用结构体指针其实也是难以避免的

而当我们对二叉树进行不从根结点开始的顺序遍历时,我们要想找到该节点的前趋和后继的结点,我们又必须从根开始遍历一遍。

要想不反复遍历,我们就有两个解决方案:
1.重新建一个数组,先遍历一遍,然后记下来。
2.即本篇文章所说的线索二叉树,这种方案相较上面的方案,不需要重新建数组,直接利用二叉树浪费的空指针完成遍历的记录。

二、线索二叉树的建立

以上图二叉树为例,要求给出该二叉树的中序遍历,线索化方法如图所示:

注意:图中我们用原来左儿子结点指针指前驱,用原来右儿子指针指后继
由此,我们得到了一个线索二叉树。
这个时候,举几个例子感受一下
1,我要求找B的中序遍历前驱:
那我们知道,中序遍历:左根右,所以找中序遍历左子树找到(不需要搜索整树)
2,我们要求E的中序遍历后继:
直接顺着右子树,过去就是。

但是考虑到这种情况:对于访问到的一个节点,其左右子树都不是空指针,那么我们如何确定这个点的指针指的是左右子还是前驱后继呢?这个问题可以通过加入一个bool类型的变量对其记录类型进行标记来解决。很容易分析出来,一个bool变量占用的内存空间一定是比一个指针占用的空间要小的。

于是,我们遍历,然后记录,便可以很轻便的解决这个遍历速度的问题。

当然了,对于较小的数据范围或者一台合格的电脑,我们很明显不需要如此去为空间操劳,但是如果我们面临着巨大的数据范围或者是在单片机上快速查询的要求,我们可以考虑这个方案。

其实,我们并不会经常用到它,但是我们需要理解其内部的利用空余空间的思想,即当我们有冗余的空间时,我们还可以利用它来准备我们后续实现某种功能所需要的东西。

三、线索二叉树的实现

#include<bits/stdc++.h>
using namespace std;// 根据既定前序与中序序列递归构造二叉树
vector<int> inorder = {4,2,7,5,1,3,8,6,9};
vector<int> preorder = {1,2,4,5,7,3,6,8,9};typedef struct ThreadNode{struct ThreadNode *ltree = NULL;struct ThreadNode *rtree = NULL;int ltag = 0;int rtag = 0;int data;
}ThreadNode,*ThreadTree;ThreadNode* BuildTree(vector<int> &preorder,vector<int> &inorder){if (preorder.empty() || inorder.empty()) return nullptr;ThreadNode *root = (ThreadNode *) malloc(sizeof(ThreadNode));root->data = preorder[0];auto inRoot = find(inorder.begin(), inorder.end(), preorder[0]);vector<int> inLeft(inorder.begin(), inRoot);vector<int> inRight(inRoot+1, inorder.end());int inLeftSize = inLeft.size(); //两种遍历数组的长度是一样的vector<int> preLeft(preorder.begin()+1, preorder.begin()+1+inLeftSize);vector<int> preRight(preorder.begin()+1+inLeftSize, preorder.end());// 5、递归处理左右子树root->ltree = BuildTree(preLeft, inLeft);root->rtree = BuildTree(preRight, inRight);return root;}void visit(ThreadNode *root){cout<<root->data<<" ";
}// 构建前序遍历函数
void Preorder(ThreadNode *root){if(root == NULL) return;Preorder(root->ltree);visit(root);Preorder(root->rtree);
}// 构建中序遍历函数
void Inorder(ThreadNode *root){if(root == NULL) return;Inorder(root->ltree);visit(root);Inorder(root->rtree);
}// 设置后序遍历函数
void Postorder(ThreadNode *root){if(root == NULL) return;Postorder(root->ltree);Postorder(root->rtree);visit(root);
} // 中序线索二叉树的改造
void InThread(ThreadNode *root, ThreadNode *pre){if(root != NULL){InThread(root->ltree,pre);if(root->ltree == NULL){root->ltree = pre;root->ltag = 1;}if(pre != NULL && pre->rtree == NULL){pre->rtree = root;pre->rtag = 1;}pre = root;InThread(root->rtree,pre);}
} int main(){ThreadNode *root = BuildTree(preorder,inorder);ThreadNode *pre = NULL;InThread(root,pre);pre->rtree = NULL;pre->rtag = 1;
}

数据结构——线索二叉树(TBT)相关推荐

  1. C语言 题目 1698: 数据结构-线索二叉树

    <大话数据结构>上的,大家可以参考一下  题目描述 在遍历二叉树的过程中,是按照一定的规则将二叉树中的结点排列成一个线性序列,从而得到二叉树中结点的先序序列或中序序列或后序序列.但是,当以 ...

  2. (原)数据结构——线索二叉树

    原文地址:http://www.cnblogs.com/Security-Darren/p/4716082.html 转载务必注明出处! 线索二叉树的思想来源于二叉树的存储结构中,存在一些空的指针域, ...

  3. 数据结构—线索二叉树

    建议将思维导图保存下来观看,或点击这里在幕布上在线观看

  4. 【Java数据结构】线索二叉树

    中序线索二叉树 线索二叉树概述 线索二叉树代码实现 线索二叉树的数据结构 线索二叉树的遍历 线索二叉树示例完整代码 线索二叉树类 ThreadedBinaryTree 线索二叉树节点类 Threade ...

  5. 【数据结构与算法分析】0基础带你学数据结构与算法分析09--线索二叉树 (TBT)

    目录 TBT 的存储结构 线索化 如果一棵二叉树,所有原本为空的右孩子改为指向该结点的中序遍历的后继,所有原本为空的左孩子改为指向该结点的中序遍历的前驱,那么修改后的二叉树被称为 线索二叉树 (Thr ...

  6. 【线索二叉树详解】数据结构06(java实现)

    线索二叉树 1. 线索二叉树简介 定义: 在二叉树的结点上加上线索的二叉树称为线索二叉树. 二叉树的线索化: 对二叉树以某种遍历方式(如先序.中序.后序或层次等)进行遍历,使其变为线索二叉树的过程称为 ...

  7. 【练习】2021下半年数据结构刷题笔记和总结 (二) 树、查找-- 不同的排序算法、二叉排序树 平衡二叉树、哈希表查找、线索二叉树、

    记录自己下半年写题目的记录.题目来自书或者网站. 练习(一)的地址: https://blog.csdn.net/qq_41358574/article/details/117098620?ops_r ...

  8. 大话数据结构15 : 线索二叉树

    基础介绍 线索二叉树就是当用链表组成的二叉树其在叶节点或者分支中有空指针时,将空指针指向自己的前驱后者后继 记录后继 记录前驱 线索二叉树 数据结构 代码实现 #include "strin ...

  9. 【Java数据结构与算法】第十一章 顺序存储二叉树、线索二叉树和堆

    第十一章 顺序存储二叉树.线索化二叉树.大顶堆.小顶堆和堆排序 文章目录 第十一章 顺序存储二叉树.线索化二叉树.大顶堆.小顶堆和堆排序 一.顺序存储二叉树 1.介绍 2.代码实现 二.线索二叉树 1 ...

最新文章

  1. 【mybatis基础】mybatis开发dao两种方法
  2. OpenCV支持向量机SVM用于非线性可分离数据
  3. 关键字super和this的使用及区别
  4. 数据处理工具(一)——Matplotlib
  5. 【MySQL】基于MySQL的SQL核心语法实战演练(三)
  6. CV Papers|计算机视觉论文推荐周报20200502期
  7. 理解CapsuleNetwork2
  8. Python 操作 PDF 的几种方法
  9. 小试牛刀--编程实现获取计算机的IP地址和计算机名
  10. C# 编译器选项 /platform(指定输出平台)32位程序运行到x64平台的问题
  11. STL容器-queue队列
  12. android语音唤醒app,breeno助手语音唤醒
  13. Pod和容器设计模式
  14. QQ邮箱发送验证码(springboot、redis整合)
  15. 微信 动画表情 骰子 猜拳
  16. 超美二次元响应引导页源码
  17. Web版2048游戏制作
  18. nth-child 与 nth-of-type
  19. provide inject
  20. 旧款 mac 电脑重装 OS X Lion 10.7.5 系统的 U 盘安装盘制作及遇到问题和解决方法

热门文章

  1. 想玩再重启计算机语言有哪些,电脑重新启动命令_电脑重新启动按哪个键
  2. 19.1 File类:构造方法、pathSeparator、separator、、getAbsolutePath、getName、length
  3. 居民消费价格指数变化新鲜出炉,这类商品同比涨幅最大
  4. 爬虫 -- 天天基金网数据简单爬取
  5. 个人日记—《八佰》电影观后感—20200823
  6. 携手共筑前端面试宝典之JQUERY篇-王大师
  7. 上海交大计算机专业的优势,计算机专业高校实力排名,清北稳居前二,上海交大上榜...
  8. 小兔兔系列寓言故事1(之所谓的朋友1)
  9. DHCP服务器介绍及配置
  10. 沈坤荣《宏观经济学教程》第3版课后答案