线索二叉树
什么是线索二叉树?简单点说就是,线索化后的二叉树。线索是指结点中指向前驱和后继的指针。二叉树即,先前提到过的二叉树,若二叉树中的结点存在空指针域,则我们可以利用此空域作为线索。那如何在二叉树的基础上构建线索二叉树?即利用基本二叉树中的空指针域,避免浪费,用来指示前驱或者后继结点,这个过程即线索化。
那问题来了
当我们遍历这种线索化后的二叉树的时候,怎么知道当前节点的指针域是子树域还是线索域呢(也就是说当前节点的指针域到底是指向子树,还是指向前驱或者后继呢?)此时,就需要在基础二叉树节点上添加标志域以解释当前指针域(即区分指针所指是孩子还是线索)
先来看二叉树节点定义
lchild | data | rchild |
---|---|---|
指示左孩子 | 数据域 | 指示右孩子 |
typedef struct _BTNode{
ElemType data;
struct _BTNode * lchild; //指示左孩子
struct _BTNOde * rchild; //指示右孩子
}BTNode;
这是关于二叉树用二叉链表实现的节点的定义,不做过多讨论,有兴趣的可以去看我的一篇关于二叉树基本操作递归非递归简单实现的文章。此处主要与线索二叉树节点做对比。
再看线索二叉树节点定义
lchild | LTag | data | RTag | rchild |
---|---|---|---|---|
指示左孩子/指示节点前驱 | 0/1 | 数据域 | 0/1 | 指示右孩子/指示节点后继 |
LTag = 0,表示lchild域指向左孩子;
LTag = 1,表示lchild域指向节点前驱;
同理
RTag = 0,表示rchild域指向右孩子;
RTag = 1,表示rchild域指向节点后继;
与单纯的二叉树节点的定义的区别就是增加了一个Tag域以区分rchild域和lchild域的作用。也可以看成是这两个指针域功能被重载了,用不同的Tag值以区别。