线索化二叉树
//线索二叉树结点
typedef struct ThreadNode {
int data;
struct ThreadNode* lchild, * rchild;
int ltag, rtag;//左、右线索标志
}ThreadNode, * ThreadTree;
//全局变量pre,指向当前访问结点的前驱
ThreadNode* pre=NULL;
void visit(ThreadNode* q)
{
if (q->lchild == NULL) {//左子树为空,建立前驱线索
q->lchild = pre;
q->ltag = 1;
}
if (pre != NULL && pre->rchild == NULL){
pre->rchild = q;//建立前驱结点的后继线索
pre->rtag = 1;
}
pre = q;
}
//中序遍历二叉树,一边遍历一边线索化
void InThread(ThreadTree T) {
if (T != NULL) {
InThread(T->lchild);//中序遍历左子树
visit(T);//访问根结点。如果为先序线索化,可以在"InThread(T->lchild)"前加一个条件"if(T->ltag==0)"防止出现无限循环的情况
InThread(T->rchild);//中序遍历右子树
}
}
//中序线索化二叉树T
void CreateInThread(ThreadTree T) {
pre = NULL;//pre初始为NULL
if (T != NULL) {//非空二叉树才能线索化
InThread(T);//中序线索化二叉树
if (pre->rchild == NULL)
pre->rtag = 1;//处理遍历的最后一个结点
}
}
线索二叉树的遍历
/以下为中序线索二叉树的遍历
//找到以p为根的子树中,第一个被中序遍历的结点
ThreadNode* FirstNode(ThreadNode* p) {
//循环找到最左下结点(不一定是叶结点)
while (p->ltag == 0)
p = p->lchild;
return p;
}
//在中序线索二叉树中找到结点p的后继结点
ThreadNode* NextNode(ThreadNode* p) {
//右子树最左下结点
if (p->rtag == 0)
return FirstNode(p->rchild);
else
return p->rchild;//rtag==1直接返回后继线索
}
//对中序线索二叉树进行中序遍历(利用线索实现的非递归算法)
void InOrder(ThreadNode* T) {
for (ThreadNode* p = FirstNode(T); p != NULL; p = NextNode(p))
visit(p);
}
//找到以p为根的子树中,最后一个被中序遍历的结点
ThreadNode* LastNode(ThreadNode* p) {
//循环找到最右下结点
while (p->rtag == 0)
p = p->rchild;
return p;
}
//在中序线索二叉树中找到结点p的前驱结点
ThreadNode* PreNode(ThreadNode* p) {
//左子树最右下结点
if (p->ltag == 0)
return LastNode(p->lchild);
else
return p->lchild;//ltag==1直接返回前驱线索
}