数据结构专升本学习,线索二叉树

前言

前面我们学习树和二叉树的一些基本操作,今天我们学习一个新的知识,学习一下线索二叉树,线索二叉树是由二叉链存储结构变化而来的(我们先得有个二叉链树,再做处理),就是将原来的空域链改为莫种遍历次序下该结点的前驱结点和后继结点的指针,就相当于把我们的空域也利用起来指向下一个要输出的结点,对于下一个结点提高了访问速度,emmm,有点难,博主也有点云里雾里,看博主的解释能不能让你理解。嘿嘿

每日一遍,快乐学习

你们第一次炒菜是不是也是这个样纸!!!!哈哈哈哈

1.什么是线索二叉树

对于n个结点的二叉树,在二叉链存储结构中有n+1个空链域,利用这些空链域存放在某种遍历次序下该结点的前驱结点和后继结点的指针,这些指针称为线索,加上线索的二叉树称为线索二叉树。这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。注意:线索链表解决了无法直接找到该结点在某种遍历序列中的前驱和后继结点的问题,解决了二叉链表找左、右孩子困难的问题。讲人话就是:(假设一个链式二叉树采用先序遍历,遍历到了叶子结点的时候发现有两个空指针域,我们前驱指向上一个遍历过的结点,后继指向先序遍历时这个结点需要遍历的下一个结点,形成线索)

2.线索二叉树的存储结构

线索二叉树主要是针对三种遍历去实现的,分别是先序中序后序遍历,线索二叉树的结点是由五个变量来表示的,为了区分左子树和右子树,我们有两个指针指向,一个前驱一个后继,为了区别这个指针是否是空指针域,我们还需要两个标记值,我们采用ltag和rltag来标记,结点结构如图:

2.1线索二叉树先序遍历逻辑图:

2.2线索二叉树中序遍历逻辑图:

2.3线索二叉树后序遍历逻辑图:

3.创建线索二叉树及基本运算

博主用的是中序遍历来对二叉树进行的线索化

3.1初始化线索二叉树的类型

typedef struct bthnode
{  char data;//我们需要存的值在data里面struct bthnode *lchild,*rchild;//两个指针表示指向左右子树,如果为空改变标志值指向遍历前后结点int ltag,rtag;//用来标记前驱和后继结点的状态,0表示有子树,1表示指向遍历前后结点
} BthNode;
//-------二叉链的基本运算算法-----------//需要先建立二叉链才能对这个这个二叉链进行线索连接
void CreateBTree(BthNode * &bt,char *str)
{   BthNode *St[MaxSize],*p=NULL;int top=-1,k,j=0;char ch;bt=NULL;          //建立的二叉树初始时为空ch=str[j];while (ch!='\0') //str未扫描完时循环{   switch(ch){case '(':top++;St[top]=p;k=1; break;   //为左孩子结点case ')':top--;break;case ',':k=2; break;                  //为右孩子结点default:p=(BthNode *)malloc(sizeof(BthNode));p->data=ch;p->lchild=p->rchild=NULL;if (bt==NULL)                   //*p为二叉树的根结点bt=p;else                          //已建立二叉树根结点{    switch(k) {case 1:St[top]->lchild=p;break;case 2:St[top]->rchild=p;break;}}}j++;ch=str[j];}
}

3.2 建立线索二叉树

BthNode *CreaThread(BthNode *bt)//需要先建立二叉链树,再到这个函数对关系进行连接
{   BthNode *head;//对以bt为根结点的二叉树中序线索化,并增加一个头结点headhead=(BthNode *)malloc(sizeof(BthNode));//给头结点划分内存head->ltag=0;head->rtag=1;  //创建头结点headhead->rchild=bt;//头结点的后继指向最后一个结点if (bt==NULL)        //bt为空树时head->lchild=head;//因为bt为空树,head->ltag=0,所以让头指向自己else{ head->lchild=bt;//更改头指针的指向,根改变了pre=head;        //pre是p的前驱结点,供加线索用Thread(bt);       //中序遍历线索化二叉树pre->rchild=head;   //最后处理,加入指向根结点的线索pre->rtag=1;head->rchild=pre;  //根结点右线索化}return head;
}
BthNode *pre;           //定义pre为全局变量
void Thread(BthNode *&p)
//对以p为根结点的二叉树进行中序线索化
{  if (p!=NULL){  Thread(p->lchild);    //左子树线索化if (p->lchild==NULL)   //前驱线索{  p->lchild=pre; //给结点p添加前驱线索p->ltag=1;}else p->ltag=0;if (pre->rchild==NULL){  pre->rchild=p;  //给结点pre添加后继线索pre->rtag=1;}else pre->rtag=0;pre=p;Thread(p->rchild);    //右子树线索化}
}

3.3销毁线索二叉树

先销毁原来的二叉链,最后释放头结点。

void DestroyBTree1(BthNode *&b)
{  if (b->ltag==0)     //b有左孩子,释放左子树DestroyBTree1(b->lchild);if (b->rtag==0)       //b有右孩子,释放右子树DestroyBTree1(b->rchild);free(b);
}
void DestroyBTree(BthNode *&tb)
{  DestroyBTree1(tb->lchild);    //释放以tb->lchild为根结点的树free(tb);           //释放头结点
}

3.4 简单操作

BthNode *FirstNode(BthNode *tb)//在中序线索树中查找中序序列的第1个结点
{  BthNode *p=tb->lchild;   //p指向根结点while (p->ltag==0)     //找根结点的最左下结点p=p->lchild;            //继续找左子树return(p);
}
BthNode *LastNode(BthNode *tb)  //在中序线索树中查找中序序列的最后1个结点
{return(tb->rchild);//因为我们的最后一个结点后继指向头,头的后继指向最后一个结点
}
BthNode *PreNode(BthNode *p)//在中序线索二叉树上,查找p结点的前驱结点
{  BthNode *pre;pre=p->lchild;//找到它的左子树if (p->ltag!=1)//如果左子树就指向p的前驱,ltag=1,因为它中序前一个为莫个树的中根while (pre->rtag==0)//往后遍历,直到为1,就它的后继就是p的前驱pre=pre->rchild;return(pre);
}
BthNode *PostNode(BthNode *p)//在中序线索二叉树上,查找p结点的后继结点
{   BthNode *post;post=p->rchild;if (p->rtag!=1)while (post->ltag==0)//和上面同理post=post->lchild;return(post);
}
void ThInOrder(BthNode *tb)//中序遍历线索二叉树,输出中序遍历序列
{   BthNode *p;p=FirstNode(tb);while (p!=tb){ printf("%c ",p->data);p=PostNode(p);}printf("\n");
}

总结

线索二叉树是基于二叉链之上的,博主的代码是用二叉链再做逻辑连接,我们也可以直接用那个类型建立线索二叉树,只要记住线索二叉树的连接规则是根据二叉树的三种遍历方法得来的,我们根据遍历来判断空域的连接,前驱指向这个遍历的结点的上一个结点,后继指向这个结点的下一个需要遍历的结点,差不多就是这样,不是很难,好了创作不易,点赞关注评论收藏哦!!!感谢大佬

线索二叉树,画图教你秒懂线索二叉树(线索二叉树的建立和简单操作)逻辑代码分析相关推荐

  1. 线索二叉树原理及前序、中序线索化(Java版)

    转载 原文地址:https://blog.csdn.net/UncleMing5371/article/details/54176252 一.线索二叉树原理 前面介绍二叉树原理及特殊二叉树文章中提到, ...

  2. 线索二叉树和中序非递归遍历线索化后的二叉树

    //线索二叉树 #include<stdio.h> #include<malloc.h> #include<process.h> #define OVERFLOW ...

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

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

  4. 二叉树的链式存储结构(线索二叉树)

    一.链式存储结构 由于顺序存储二叉树的空间利用率较低,因此二叉树一般都采用链式存储结构,用链表结点来存储二叉树中的每个结点.在二叉树中,结点结构通过包括若干数据域和若干指针域,二叉链表至少包含3个域: ...

  5. 线索二叉树(C语言实现)——后续线索链表

    #include<stdio.h> #include<stdlib.h> #include<stdbool.h> typedef char DataType;// ...

  6. 万字教你入门数据结构(C语言)二叉树

    树的概念和结构 树的表示 孩子兄弟表示法 二叉树概念及其结构 堆的概念 堆的实现 大堆 小堆 堆排序 和TopK问题 链式二叉树概念 及其结构实现 树的概念和结构 树 是一种非线性的数据结构 任意一棵 ...

  7. java 二叉树的高度_最全二叉树:完整详解二叉树的遍历以及完全二叉树等6种二叉树...

    树在数据结构中占据了非常重要的位置,尤其是二叉树.经常是在java面试中必问的一个环节,而且二叉树的应用场景真的非常普遍,需要重点掌握好. 但是一直以来,很多同学对于二叉树的掌握都是不太全面.今天我就 ...

  8. 【数据结构之二叉树】——二叉树的概念及结构,特殊的二叉树和二叉树性质

    文章目录 一.二叉树的概念及结构 1.概念 2.现实中的二叉树 3. 特殊的二叉树: 3.二叉树的性质 二.二叉树练习题 总结 一.二叉树的概念及结构 1.概念 一棵二叉树是结点的一个有限集合,该集合 ...

  9. 数据结构-二叉树(包含二叉树的层次建树、前中后序遍历、层次遍历解析及代码)

    目录 一.树与二叉树的原理解析 1.树的定义 2.树的结构和特点 3.二叉树的定义 4.树结点的数据结构 二.二叉树的层次建树 1.二叉树层次建树的原理及分析 2.完整代码 三.二叉树的前中后序遍历 ...

最新文章

  1. Java多线程:Semaphore
  2. 计算机序号函数,EXCEL函数自动编号/编码单条件和多条件的几种方法
  3. 剑指云原生数据库 2.0,阿里云发布全新一站式敏捷数据仓库解决方案
  4. JavaScript错误处理和堆栈追踪浅析
  5. springBoot的一些注解以及静态资源的处理
  6. Java列表removeAll(Collection)示例
  7. 生产者-消费者习题的运用
  8. adb 命令 monkey命令
  9. java ftp下载文件夹下的所有文件_ftp下载文件夹下的文件,从ftp下载某一文件夹下的所有文件...
  10. 可能是catalan数吧
  11. excel 隐藏和取消隐藏
  12. 从一位前阿里P7被裁员,聊技术人的第二职业!
  13. 49种软件验收测试方法大分享,快来看
  14. 【autojs】Auto.js Pro免root打开无障碍服务(需adb授权,重启手机不失效)脚本源代码
  15. 测序技术回顾与第三代测序技术展望
  16. scipy.misc.imresize的替换方案
  17. 7 c4d r20对win_OC渲染器Octane Render V4.0-RC7-R4 for C4D R15-R19-R20 Win/Mac
  18. windows 2003 下SERVU:无法开始服务器.服务器执行缺少
  19. oa系统服务器价格,oa软件系统价格
  20. 重庆市委统战部慰问全市唯一健在南侨机工

热门文章

  1. 经纬度坐标转平面坐标(C++)
  2. leetcode链表之反转链表
  3. raft partd 日志压缩 部署指导
  4. 老男孩教育 | 0基础转行学运维,收获薪资13K Offer!
  5. 数字图像处理——图像质量评价(Python)
  6. 【uni-app从入门到实战】组件学习
  7. Tips of Terminal
  8. ranger操作介绍
  9. C# vb .NET读取识别条形码线性条码code128
  10. Unity 粒子系统贴图去除黑色区域