(原创)线索二叉树那点小破事

线索二叉树


二叉树的基本定义结构我们都很熟悉,节点数据加上孩纸指针,左孩子指娘家,右孩子指婆家,我们来看这个例子:

我们会发现,有些孩子并没有地方可以去,例子中的树一共十个结点,十一个空闲指针,由此引出我们对于空闲指针的计算公式:一个有 n 个结点的二叉树有 2n 个指针域,而 n 个结点会产生 n-1 个分支,每个分支对应其指向孩子的指针域,所以空闲指针数: 2n - (n-1) = n+1 ,这么多指针域我们怎样规划能避免这些指针便宜null呢?

大佬们提出了这样一个用途,中序遍历这棵树我们可以得到: HDIBJEAFCG ,很轻松。那么我们可以愉快的知道 I 是 B 的前驱,或者 J 是 B 的后继这样的信息,那是借助了遍历,我们能不能把这些空的指针指向前驱和后继呢,当然阔以。

但是马上有人站出来说,那指向孩子的指针原来就存在了,这后来的野生指针和指向孩子的指针可怎么区分呢,大佬们就决定再加个量来区分指针的类型,如果是指向孩子的就用 0 表示,用作前驱后继的就用 1 表示,使用的时候进行遍历就可以一劳永逸地取得前驱后继的信息,OK,看看结构的定义变成啥样了。

和原来差不多对不对,多了个枚举变量的定义

OK,现在我们的线索二叉树可以算正式出炉辽:

我们把指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树就称为线索二叉树 (Threaded Binary Tree)

来看一看抽象化结点的结构:ltag = 0 或者 Link,表示这个结点的左指针指向左孩子,ltag = 1 或者 Thread,表示这个结点的左指针指向前驱

rtag = 0 或者 Link,表示这个结点的右指针指向右孩子,rtag = 1 或者 Thread,表示这个结点的右指针指向后继

结点的新式定义

改头换面的二叉链表

中序线索化遍历的实现

我们来读一下代码,朴素的中序遍历的框架其实还在,中间加粗的是线索化的代码,另外多了 pre 的指针,我们可以发现这个指针永远比我们的主角指针 p 慢一拍,它永远在 p 的前驱结点,每次到了一个结点,我们先判断一哈这个结点有没有左子树,如果没有,就使这个节点的标记值置Thread,表示这个结点被前驱大爷承包了,然后就是让指针 p 的左孩子管 pre 叫干爹, 表示这个结点的前驱就定下了;然后是后继,我们会发现这个和前驱有点不同,这个先看前驱结点的右孩子是否为空,即 如果 pre -> rchild 为空,就把这个引到 p 指针,我们说 p 指针走的快一步,所以这就找到了后继,顺理成章  pre->rtag = Thread,pre -> rchild = p; 完美! 这两步表示一轮线索化的一个轮回,弄完这些让 pre 再向前走一步,就是 pre = p,剩下的和中序遍历没什么区别

我们给这个二叉链表加上一个头指针,并且让头结点的左孩子指向树根节点,让中序的第一个节点指回头结点的左孩子指针,用头结点的右指针指向中序遍历的最后一个结点,并且把这个指针指回头结点的右指针,形成双向的指针循环,这样的好处就在于既可以从第一个结点开始沿中序的后继向后遍历,也可以利用从头开始前序遍历(例子及表述来自《大话数据结构》)


附上带头结点的线索二叉树中序遍历:


首先定义指向根的头结点 p,我们先看外层这个最大的循环,这个循环条件为 p != T ,这个条件首先排除了空树的遍历,其次按照刚才对带头节点二叉线索表的分析,最后的 p 指针会在穷途末路时等于 T ,这相当于 p 指向头结点,这时 p = T ,故如果不加 p != T ,则会无限循环下去。进入循环,首先是判定p -> ltag 等于Link,内容是指向左子树,那么这一个循环表示从根开始直到没有左子树的末端,路径是A →B→D→H,然后打印H,目前 p 的右指针是指向直接后继D的,所以下面一个进入第二个while,打印出D,D的右边是孩子指针,第十五行指向I,然后重复整个过程,相当于从小树到大树以链表搜索的形势进行完整的中序遍历,完整顺序参照下图


好的,我们今天的线索二叉树就到这里辽,最后附上一段我偷来的话:


在实际问题中 ,如果所用的二叉树需经常遍历或查找结点时需要某种遍历序列中的前驱和后继,那么采用线索二叉链表的存储结构就是非常不错的选择。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • 目录 1、什么是树 2、相关术语 3、二叉树 3.1、二叉树的类型 3.2、二叉树的性质 3.3、二叉树的结构 3...
    我哈啊哈啊哈阅读 2,543评论 0 10
  • 1.树和二叉树的定义 (1) 树的定义 树是n (n≥0) 个结点的有限集。 n=0 时称为空树。在任意一棵非空树...
    yinxmm阅读 2,449评论 0 3
  • 四、树与二叉树 1. 二叉树的顺序存储结构 二叉树的顺序存储就是用数组存储二叉树。二叉树的每个结点在顺序存储中都有...
    MinoyJet阅读 1,524评论 0 7
  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,745评论 0 13
  • 文 | 花开半夏香如故 享受假期,享受美食。大部分女孩子喜欢吃甜点,其中松软可口的蛋糕就是甜点中,相当有治愈作用的...
    花开半夏香如故阅读 802评论 11 16