【数据结构和算法】线索二叉树

简介: 【数据结构和算法】线索二叉树

利用二叉链表中的空指针域:

  • 如果某个节点的左孩子为空,则将空的左孩子的指针域改为指向其前驱;
  • 如果某个节点的右孩子为空,则将空的右孩子的指针域改为指向其后继;
  • 这种改变指向的指针称为“线索”,加上了线索的二叉树称为线索二叉树,对二叉树按某种遍历次序使其变为线索二叉树的过程叫做线索化。


为区分lchild和rchild指针到底是指向孩子的指针还是指向前驱后继的指针,对二叉链表的每个结点增设两个标识域ltag和rtag,并约定:

  • ltag = 0 lchild指向该节点的左孩子
  • ltag = 1 lchild指向该节点的前驱
  • rtag = 0 rchild指向该节点的右孩子
  • rtag = 1 rchild指向该节点的后继


增加头结点

增加一个头结点

  • ltag = 0,lchild指向根节点
  • rtag = 1,rchild指向遍历序列中最后一个结点
  • 遍历序列中第一个节点的lc域和最后一个结点的rc域都指向头结点,如图所示。
  • image.png
  • 找到了前驱,就可以找到头结点,通过头结点又可以访问到其他的节点;
  • 而当我们找到了最后的一个节点,有可以顺着指针找到头结点再找到其他的节点。


线索二叉树的数据结构

typedef enum{
  link, //表示指向左右孩子的指针
  thread, //表示指向前驱后继的线索
}TreePointTag;
typedef struct TbinaryTree{
  char data;
  struct TbinaryTree *lchild;
  struct TbinaryTree *rchild;
  TreePointTag ltag;
  TreePointTag rtag;
}TbinaryTree;


代码:

//线索二叉树的数据结构
typedef enum{link,thread}PointTag;
typedef struct BiThrNode{
  char data;
  struct BiThrNode *lchild;
  struct BiThrNode *rchild;
  PointTag ltag;
  PointTag rtag;
}BiThrNode,*BiThrTree;
//线索二叉树的创建
BiThrNode* CreateBiThrTree()
{
  BiThrNode* T;
  char c;
  scanf("%c",&c);
  if(' ' == c)
  T = NULL;
  else
  {
  T = (BiThrNode *)malloc(sizeof(BiThrNode));
  T->data;
  T->data = c;
  T->ltag = link;
  T->rtag = link;
  T->lchild = CreateBiThrTree();
  T->rchild = CreateBiThrTree();
  }
  return T;
}
//全局变量,始终指向刚刚访问过的节点
BiThrTree pre;
//中序遍历线索化
InThreading(BiThrTree T)
{
  if(T)
  {
  InThreading(T->lchild); //递归左孩子线索化
  //节点处理,中序和之前遍历树的操作不同,但是结构相同  
  if( !T->lchild)   //如果该节点没有左孩子
  {
    T->ltag = thread; //设置为线索
    T->lchild = pre;  //指向前驱节点,也就是上一个访问的节点
  }
  if( !pre->rchild )  //右子树为空的情况才可以设置线索
  {
    pre->rtag = thread; //设置为线索
    pre->rchild = T;  //指向后继节点,也就是当前访问的节点
  }  
  pre = T;  //处理完当前节点之后,T就成为前一个节点,然后接着往下
  InThreading(T->rchild); //递归右孩子线索化
  }
}
//增加头结点并对pre进程初始化
InOrderThreading(BiThrTree head,BiThrTree T)
{
  head = (BiThrTree)malloc(sizeof(BiThrTree));
  head->ltag = link;
  head->rtag = thread;
  head->rchild = head;  //指向本身
  if( !T )  //如果为空树
  head->lchild = head;
  else  //如果不是空树
  {
  head->lchild = T;
  pre = head;  //对pre进行初始化
  InThreading(T); //中序遍历线索化
  //收尾处理
  pre->rchild = head;
  pre->rtag = thread;
  head->rchild = pre;
  }
}
//中序遍历二叉树,非递规
void InOrderTraverse(BiThrTree T)
{
  BiThrTree p;
  p = T->lchild;
  while( p != T )
  {
  while( p->ltag == link )
    p = p->lchild;
  printf("%c",p->data);
  while(p->rtag == thread && p->rchild != T)
  {
    P = P->rchild;
    printf("%c",p->data);
  }
  p = p->rchild;  //指回头结点
  }
}


参考链接:https://www.bilibili.com/video/av35340088

目录
相关文章
|
8月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
377 1
|
8月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
210 0
|
12月前
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
370 10
 算法系列之数据结构-二叉树
|
12月前
|
算法 Java
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
365 3
 算法系列之数据结构-Huffman树
|
12月前
|
算法 Java
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
500 22
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
451 30
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
637 25
|
5月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
497 0
|
5月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
325 2
|
6月前
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
307 3