文章目录
1. 线索二叉树
1.1 线索二叉树的概念
线索二叉树的概念是基于二叉树的链式存储的;
在传统的二叉链表存储中,仅能体现一种父子关系,不能直接得到各个结点在遍历中的前驱和后继;
同时在链式存储中,每个叶节点都有2个空指针,所以我们设想能否利用这些空指针来存放指向其前驱或后继结点。
这样不仅能提高存储空间的利用效率,同时还可以在遍历中方便的查找前驱和后继结点。
1.2 线索二叉树的结点结构
![](https://i-blog.csdnimg.cn/blog_migrate/e9c102c8e5cf1dc8ef209b4391bd96b9.png#pic_center)
// 线索二叉树结点
typedef struct ThreadNode
{
ElemType data;
struct ThreadNode *lchild, *rchild;
// 相比普通的二叉树只多了这2个变量
// 左,右线索标志;用来表明该结点的左,右指针指向的是线索还是孩子结点
int ltag, rtag;
}ThreadNode, *ThreadTree;
1.3 三种线索二叉树的线索化示意图
(1)中序线索二叉树
线索指向中序遍历的前驱结点,中序遍历的后继结点。
图示二叉树的中序遍历(左根右)为:D G B E A F C
- 前驱线索,由左孩子指针充当,是黄色虚线
- 后继线索,由右孩子指针充当,是紫色虚线
详细图示(红色数字表示的是“中序遍历”的序列):
(2)先序线索二叉树
线索指向先序遍历的前驱结点,中序遍历的后继结点。
图示二叉树的先序遍历(根左右)为:A B D G E C F
详细图示:
(3)后续线索二叉树
线索指向后序遍历的前驱结点,中序遍历的后继结点。
图示二叉树的后序遍历(左右根)为:G D E B F C A
详细图示:
2. 二叉树的线索化(C语言代码实现)
二叉树线索化的核心就是对中序/先序/后序遍历算法(递归实现)进行改造,用一个指针 pre 记录当前访问结点的前驱结点,在具体访问一个结点时,连接该结点与该结点的前驱结点的线索信息。
2.1 线索二叉树的结点结构定义
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100
struct ElemType
{
int value;
};
// 线索二叉树结点
typedef struct ThreadNode
{
ElemType data;
struct ThreadNode *lchild, *rchild;
// 相比普通的二叉树只多了这2个变量
// 左,右线索标志;用来表明该结点的左,右指针指向的是线索还是孩子结点
int ltag, rtag;
}ThreadNode, *ThreadTree;
// 定义一个全局变量 pre,指向当前访问节点的前驱
ThreadNode *pre = NULL;
2.2 线索化公共部分代码
前面已经介绍过,主要修改的是访问结点的那部分代码。
(1)图示(中序线索化)
q 指针,指向当前遍历的结点;pre 指针,指向当前遍历结点的前一个结点。
特别注意
- 建立前驱线索(黄色虚线)时,一定是 pre 指针指向黄色虚线箭头的末尾结点,q 指针指向黄色虚线箭头的开始结点。
- 建立后继线索(紫色虚线)时,一定是pre指针指向紫色虚线的开头结点,q指针指向紫色虚线的末尾结点
(2)代码
// 访问某个节点
void visit