线索二叉树的定义

充分利用二叉链表中的空链域,将遍历过程中结点的前驱、后继信息保存下来。

  • 若结点有左子树,则其 LChild 域指向其 左孩子,否则 LChild 域指向其 前驱结点

  • 若结点有右子树,则其 RChild 域指向其 右孩子,否则 RChild 域指向其 后继结点

  • 线索:在这种存储结构中,指向前驱和后继结点的指针叫做线索。

  • 线索链表:以这种结构组成的二叉链表作为二叉树的存储结构,叫做线索链表。

  • 线索化:对二叉树以某种次序进行遍历并且加上线索的过程叫做线索化。

  • 线索二叉树:线索化了的二叉树称为线索二叉树。

typedef struct TBTNode
{char data;int ltag,rtag;struct TBTNode *lchild;struct TBTNode *rchild;
}TBTNode;


二叉树中序线索化

中序遍历 {H、D、I、B、J、E、A、F、C、G}

分成三个步骤

(1)左子树线索化
(2)建立当前结点 p 与前驱结点 pre 的线索
(3)右子树线索化

注意:每次线索化之前需要确定好当前结点 p 和前驱结点 pre,即按照中序遍历的顺序

  1. p 结点是H,pre 结点是NULL —— 对应步骤(1)
  2. p 结点是D,pre 结点是H —— 对应步骤(2)
  3. p 结点是I,pre 结点是D —— 对应步骤(3)
  4. p 结点是B,pre 结点I —— 对应步骤(2)

(1)建立中序线索二叉树

void InThread(TBTNode *p,TBTNode *&pre)
{if(p!=NULL){InThread(p->lchild,pre);   // 递归,左子树线索化if(p->lchild==NULL)     // 建立当前结点的前驱线索{p->lchild=pre;p->ltag=1;}if(pre!=NULL&&pre->rchild==NULL)  //建立前驱结点的后继线索{pre->rchild=p;pre->rtag=1;}pre=p;InThread(p->rchild,pre); // 递归,右子树线索化}
}
void createInThread(TBTNode *root)
{TBTNode *pre=NULL;    //  前驱结点指针if(root!=NULL){InThread(root,pre);pre->rchild=NULL;  // 处理最后一个结点的后继pre->rtag=1;}
}

(2)遍历中序线索二叉树

TBTNode *First(TBTNode *p)   //  找到最左下的结点
{while(p->ltag==0)p=p->lchild;return p;
}TBTNode *Next(TBTNode *p)
{if(p->rtag==0)    //  如果p存在右孩子,则p的后继结点是p的右子树中的最左下结点return First(p->rchild);return p;
}void Inorder(TBTNode *root)
{for(TBTNode *p=First(root);p!=NULL;p=Next(p))Visit(p);
}

二叉树前序线索化

前序遍历 {A、B、D、H、I、E、J、C、F、G}

分成三个步骤

(1)建立当前结点 p 与前驱结点 pre 的线索
(2)左子树线索化
(3)右子树线索化

注意:每次线索化之前需要确定好当前结点 p 和前驱结点 pre,即按照中序遍历的顺序

  1. p 结点是A,pre 结点是NULL —— 对应步骤(1)
  2. p 结点是B,pre 结点是A —— 对应步骤(2)
  3. p 结点是D,pre 结点是B —— 对应步骤(3)
  4. p 结点是H,pre 结点D —— 对应步骤(2)

(1)建立前序线索二叉树

void preThread(TBTNode *p,TBTNode *&pre)
{if(p!=NULL){if(p->lchild==NULL)      // 建立当前结点的前驱线索{p->lchild=pre;p->ltag=1;}if(pre!=NULL&&pre->rchild==NULL)  //建立前驱结点的后继线索{pre->rchild=p;pre->rtag=1;}pre=p;preThread(p->lchild,pre);    // 递归,左子树线索化preThread(p->rchild,pre); // 递归,右子树线索化}
}
void createPreThread(TBTNode *root)
{TBTNode *pre=NULL;    //  前驱结点指针if(root!=NULL){preThread(root,pre);pre->rchild=NULL; // 处理最后一个结点的后续pre->rtag=1;}
}

(2)遍历前序线索二叉树

void preorder(TBTNode *root)
{if(root!=NULL){TBTNode *p=root;while(p!=NULL){while(p->ltag==0)    //  存在左孩子,则边访问边左移{Visit(p);p=p->lchild;}Visit(p);    //  不存在左孩子,只访问不左移p=p->rchild;    //  因为不存在左孩子,所以向其右孩子或者后继结点移动}}
}

二叉树后序线索化

后序遍历 {H、I、D、J、E、B、F、G、C、A}

分成三个步骤

(1)左子树线索化
(2)右子树线索化
(3)建立当前结点 p 与前驱结点 pre 的线索

注意:每次线索化之前需要确定好当前结点 p 和前驱结点 pre,即按照中序遍历的顺序

  1. p 结点是H,pre 结点是NULL —— 对应步骤(1)
  2. p 结点是I,pre 结点是H —— 对应步骤(2)
  3. p 结点是D,pre 结点是I —— 对应步骤(3)
  4. p 结点是J,pre 结点D —— 对应步骤(2)

(1)建立后序线索二叉树

void postThread(TBTNode *p,TBTNode *&pre)
{if(p!=NULL){preThread(p->lchild,pre);  // 递归,左子树线索化preThread(p->rchild,pre); // 递归,右子树线索化if(p->lchild==NULL)     // 建立当前结点的前驱线索{p->lchild=pre;p->ltag=1;}if(pre!=NULL&&pre->rchild==NULL)  //建立前驱结点的后继线索{pre->rchild=p;pre->rtag=1;}pre=p;}
}
void createPostThread(TBTNode *root)
{TBTNode *pre=NULL;    //  前驱结点指针if(root!=NULL){postThread(root,pre);pre->rchild=NULL;    // 处理最后一个结点的后续pre->rtag=1;}
}

树 —— 线索二叉树相关推荐

  1. 【数据结构-树】2.二叉树遍历与线索二叉树(图解+代码)

    一.二叉树的定义及其主要特征 1.1 二叉树的概念 二叉树是另一种树形结构,其特点是每个结点最多含两棵子树(也就是说,二叉树的度≤2). 二叉树是一种有序树,若将其左.右子树颠倒,则成为另一颗不同的二 ...

  2. 线索二叉树(基于链表存储树结点)

    有以下场景 如果使用中序遍历,那么得到的顺序是:HDIBEAFCG,可以得知A的前驱结点为E,后继结点为F.但是,这种关系的获得是建立在完成遍历后得到的.如果我们每次想得到某个节点的前驱或者后继,都要 ...

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

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

  4. 二叉树前序中序后续线索树_二叉树的先序,中序,后序遍历以及线索二叉树的遍历...

    二叉树的先序,中序,后序遍历以及线索二叉树的遍历 (2008-05-04 17:52:49) 标签: 杂谈 C++ 二叉树的先序,中序,后序遍历以及线索二叉树的遍历 头文件 //*********** ...

  5. 线索二叉树、选择树、堆

    线索二叉树: 规律:在n个节点的链式二叉树中必定有n+1个空指针域 有序链式二叉树中有很多空指针,可以让这些指针指向下一个或者前一个节点,这样在遍历时不用递归而可以使用循环遍历,可以提高树的遍历速度 ...

  6. 数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

    在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉 ...

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

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

  8. 【数据结构Note5】- 树和二叉树(知识点超细大全-涵盖常见算法 排序二叉树 线索二叉树 平衡二叉树 哈夫曼树)

    文章目录 5.1 树和二叉树引入 5.1.1 树的概念 5.1.2 树的表示 5.1.3 树中基本术语 5.2 二叉树 5.2.1 概念 5.2.2 二叉树的性质 5.2.3 特殊的二叉树 5.2.4 ...

  9. 常用数据结构之线索二叉树和哈夫曼树

    1.线索二叉树 上一篇二叉树中,我们介绍了基本的二叉树的结构.每一个父节点对应两个子节点,左子节点和右子节点.其中我们会看到,很多节点的左右节点都为null,为了更高效的存储和遍历,我们考虑一种方式将 ...

最新文章

  1. git/gitee操作手册
  2. 城镇开发边界划定指南_URP精编 | 基于 “双评价”的城镇开发边界划定实证研究...
  3. word文档怎么限制编辑(禁止编辑、只读)?
  4. 78. 子集022(回溯法)
  5. 在洛谷开了一个邀请赛
  6. html文档的基本类型,HTML(网页的文档类型介绍)
  7. 注入dll到explorer.exe中无反应_MBR膜生物反应器的安装及技术要求都有什么呢?
  8. Bootstrap3 代码-程序输出
  9. 漫步最优化四十一——Powell法(下)
  10. Linux的一些简单命令操作
  11. SpringCache 集成 Redis,这才是优雅的缓存解决方案!
  12. windows安装python2.7_Windows下安装python2.7及科学计算套装
  13. 测试到产品经理的进阶之路
  14. Qt--自定义Delegate
  15. python 小达人_python小白入门基础(五:字符串)
  16. 华为荣耀8C安装Google play store的记录
  17. (专升本)PowerPoint(插入超链接和动作)
  18. Gradle基础:7:Property使用方式
  19. Windows 10配置远程开机
  20. 什么技术都只懂一点的蹩脚程序员

热门文章

  1. matlab绘制引力场_玩引力场和漂亮的色彩
  2. 数据挖掘——机器学习
  3. php+html+css制作非常好看网站登录与注册界面
  4. linux下开启、关闭、重启mysql服务命令
  5. 请仔细品味--俞敏洪励志演讲
  6. 基于STM32单片机的篮球计时记分器仿真设计
  7. win10怎么用计算机的搜索,win10搜索文件内容怎么操作_win10如何搜索文档内的内容...
  8. [附源码]java毕业设计网上点餐系统
  9. sap 中怎样把非限制库存转为销售订单库存?
  10. Linux C/C++ 获取系统时间