一、引出线索二叉树的原因
-
普通二叉链表:n 个结点,总共有 `2n` 个指针域
-
有效孩子指针只用了 `n-1` 个
-
剩余n+1 个指针是空指针,极度浪费空间
思路:把空指针利用起来
-
左空指针 → 指向该结点---遍历前驱
-
右空指针 → 指向该结点---遍历后继
这种用指针记录遍历先后关系的二叉树 = 线索二叉树
二、线索二叉树结点结构
比普通二叉结点多两个标记位:
-
`data`:数据
-
`lchild`:左孩子 / 前驱线索
-
`rchild`:右孩子 / 后继线索
-
`ltag`:左标记
-
`ltag = 0`:lchild 指向左孩子
-
`ltag = 1`:lchild 是前驱线索
-
`rtag`:右标记
-
`rtag = 0`:rchild 指向右孩子
-
`rtag = 1`:rchild 是后继线索
三、三种线索二叉树
按照遍历方式划分:
1.先序线索二叉树
-
中序线索二叉树
-
后序线索二叉树
四、核心特点
- 充分利用空闲空指针,不额外占用内存
2.不用递归、不用栈,就可以遍历整棵树
-
可以快速查找结点在遍历序列中的前驱、后继
-
遍历速度更快,空间复杂度更低
-
本质:二叉树 + 静态链表
五、中序线索二叉树规律
-
最左结点:左线索为空,无前驱
-
最右结点:右线索为空,无后继
-
叶子结点:左右全是线索
-
二叉树 + 头尾结点连成循环双向线索链表
找前驱后继
-
叶子结点:直接顺着线索找
-
非叶子结点:依然要靠左右子树查找
六、优缺点
优点
-
非递归遍历二叉树,无需栈
-
快速查询前驱、后继结点
-
空间利用率高
缺点
-
插入、删除结点麻烦,需要重新修改线索
-
先序、后序线索树查找前驱后继复杂
-
不如递归遍历代码直观