一、线索二叉树的定义
我们使用二叉树时,n个节点的二叉树至少会产生n+1个空指针;同时,在某种遍历方式下寻找到其前驱或后驱节点并不方便,为了解决这个问题,我们可以将这些空指针记录前后驱的关系,从而在节约空间的同时方便遍历。
我们使所有原本为空的rchild指针改为指向该节点在某序序列中的后继,所有原本为空的lchild指针改为指向该节点的某序序列的前驱。
由以上定义可知,二叉树的线索化何其遍历的方式有关。下图就是不同遍历顺序形成的线索二叉树
那么,我们又如何知道二叉树的lchild指向的是左子节点还是前驱呢?我们可以定义标位符ltag和rtag。并规定:ltag==0,指向左子节点;ltag==1,指向前驱结点。rtag==0,指向右子节点;rtag==1,指向后继结点。这样,我们写出线索二叉树的存储结构:
typedef struct bitreenode {
int data;
struct bitreenode* lchild, * rchild;
int ltag, rtag;
}bitreenode;
二、中序线索化算法
在二叉树中序遍历过程中,“访问结点”的行为就是将结点的空指针改为指向中序前驱或中序后继的线索。设指针T指向当前访问的结点,为了记下结点的前驱、后继关系,设置一个初值为NULL 的全局指针变量 pre,令 pre始终指向当前访问结点T的直接前驱,即pre是T的中序前驱,T是pre的中序后继。这样,“访问结点”执行的操作是:如果pre有空的rchild,则填写pre的rtag,令其指向T;如果T有空的lchild,则填写T的ltag,令其指向pre。
// 通过中序遍历对二叉树线索化的递归算法:
bitreenode* pre = NULL;//保持