线索二叉树的基本概念
规定:若无左子树,令lchild指向其前驱结点;若无右子树,令rchild指向其后继节点。
如图所示:增加俩个标志域标识指针域是指向左(右)孩子还是指向前驱(后继)。
lchild | ltag | data | rtag | rchild |
其中,标志域的含义如下:
ltag | 0 | lchild域指示结点的左孩子 |
1 | lchild域指示结点的前驱 | |
rtag | 0 | rchild域指示结点的右孩子 |
1 | rchild域指示结点的猴急 |
线索二叉树的存储结构描述如下:
typedef struct ThreadNode{
ElemType data; //数据元素
struct ThreadNode *lchild, *rchild; //左、右孩子指针
int ltag, rtag; //左、右线索标志
}ThreadNode, *ThreadTree;
这种结点结构构成的二叉链表作为二叉树的存储结构,称为线索链表,其中指向结点前驱和后继的指针称为线索。加上线索的二叉树称为线索二叉树。
中序线索二叉树的构造
以中序线索二叉树的建立为例。附设指针pre指向刚刚访问过的结点,指针p指向正在访问的结点,即pre指向p的前驱。在中序遍历的过程中,检查p的左指针是否为空,若为空就将它指向pre;检查pre的右指针是否为空,若为空就将它指向p。
通过中序遍历对二叉树线索化的递归算法如下:
void InThread(ThreadTree &p, ThreadTree &pre){
if(p != NULL){
InThread(p -> lchild, pre); //递归,线索化左子树
if(p -> lchild == NULL){ //左子树为空,建立前驱线索
p -> lchild = pre;
p -> ltag = 1;
}
if(pre != NULL && pre -> rchild == NULL){
pre -> rchild = p; //建立前驱结点的后继搜索
pre -> rtag = 1;
}
pre = p; //标记当前结点成为刚刚访问过的结点
InThread(p -> rchild, pre); //递归,线索化右子树
}//if(p != NULL)
}
通过中序遍历建立中序线索二叉树的主过程算法如下:
void CreateInThread(ThreadTree T){
ThreadTree pre = NULL;
if(T != NULL){ //非空二叉树,线索化
InThread(T, pre); //线索化二叉树
pre -> rchild = NULL; //处理遍历的最后一个结点
pre -> rtag = 1;
}
}
未完结