目录
一、用土方法找到中序前驱
二、中序线索化
三、中序线索二叉树
四、中序线索化(王道教材版)
五、先序线索化
六、先序线索化(王道教材版)
七、后序线索化
八、后序线索化(王道教材版)
九、总结
//中序遍历
void InOrder(BiTree T){
if(T != NULL){
InOrder(T->lchild); //递归遍历左子树
visit(T); //访问根结点
InOrder(T->rchild); //递归遍历右子树
}
}
//访问结点q
void visit(BiTNode * q){
if(q == p) //当前访问结点刚好是结点p
final = pre; //找到p的前驱
else
pre = q; //pre指向当前访问的结点
}
//辅助全局变量,用于查找结点p的前驱
BiTNode *p; //p指向目标结点
BiTNode *pre = NULL; //指向当前访问结点的前驱
BiTNode *final = NULL; //用于记录最终结果
//全局变量pre,指向当前访问结点的前驱
ThreadNode *pre = NULL;
//中序线索化二叉树T
void CreateInThread(ThreadTree T){
pre = NULL; //pre初始化为NULL
if(T != NULL){ //非空二叉树才能线索化
InThread(T); //中序线索化二叉树
if(pre->rchild == NULL)
pre->rtag = 1; //处理遍历的最后一个结点
}
}
//线索二叉树结点
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左、右线索标志
}ThreadNode,*ThreadTree;
//中序遍历二叉树,一边遍历一边线索化
void InThread(ThreadTree T){
if(T != NULL){
InThread(T->lchild); //中序遍历左子树
visit(T); //访问根节点
InThread(T->rchild); //中序遍历右子树
}
}
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 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);
}
}
//中序线索二叉树T
void CreateInThread(ThreadTree T){
ThreadTree pre = NULL;
if(T != NULL){
InThread(T,pre);
pre->rchild = NULL;
pre->rtag = 1;
}
}
//全局变量pre,指向当前访问结点的前驱
ThreadNode *pre = NULL;
//中序线索化二叉树T
void CreateInThread(ThreadTree T){
pre = NULL; //pre初始化为NULL
if(T != NULL){ //非空二叉树才能线索化
InThread(T); //中序线索化二叉树
if(pre->rchild == NULL)
pre->rtag = 1; //处理遍历的最后一个结点
}
}
//线索二叉树结点
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左、右线索标志
}ThreadNode,*ThreadTree;
//中序遍历二叉树,一边遍历一边线索化
void InThread(ThreadTree T){
if(T != NULL){
visit(T); //访问根节点
if(T->ltag == 0)
InThread(T->lchild); //中序遍历左子树
InThread(T->rchild); //中序遍历右子树
}
}
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 p,ThreadTree &pre){
if(p != NULL){
if(p->lchild == NULL){ //左子树为空,建立前驱线索
p->lchild = pre;
p->ltag = 1;
}
if(pre != NULL && pre->rchild == NULL){
pre->rchild = p; //建立前驱结点的后继线索
pre->rtag = 1;
}
pre = p;
if(p->ltag == 0)
InThread(p->rchild,pre);
InThread(p->lchild,pre); //递归、线索化左子树
}
}
//先序线索二叉树T
void CreateInThread(ThreadTree T){
ThreadTree pre = NULL;
if(T != NULL){
InThread(T,pre);
pre->rchild = NULL;
pre->rtag = 1;
}
}
//全局变量pre,指向当前访问结点的前驱
ThreadNode *pre = NULL;
//中序线索化二叉树T
void CreateInThread(ThreadTree T){
pre = NULL; //pre初始化为NULL
if(T != NULL){ //非空二叉树才能线索化
InThread(T); //中序线索化二叉树
if(pre->rchild == NULL)
pre->rtag = 1; //处理遍历的最后一个结点
}
}
//线索二叉树结点
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左、右线索标志
}ThreadNode,*ThreadTree;
//中序遍历二叉树,一边遍历一边线索化
void InThread(ThreadTree T){
if(T != NULL){
InThread(T->lchild); //中序遍历左子树
InThread(T->rchild); //中序遍历右子树
visit(T); //访问根节点
}
}
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 PostThread(ThreadTree p,ThreadTree &pre){
if(p != NULL){
PostThread(p->lchild,pre);
PostThread(p->rchild,pre);
if(p->lchild == NULL){
p->lchild = pre;
p->ltag = 1;
}
if(pre != NULL && p->rchild == NULL){
pre->rchild = p;
pre->rtag = 1;
}
pre = p;
}
}