王道数据结构笔记——二叉树线索化

目录

一、用土方法找到中序前驱

二、中序线索化

三、中序线索二叉树

四、中序线索化(王道教材版)

五、先序线索化

六、先序线索化(王道教材版)

七、后序线索化

八、后序线索化(王道教材版)

九、总结


一、用土方法找到中序前驱

//中序遍历
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;
    }
}

九、总结

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章