王道數據結構筆記——二叉樹線索化

目錄

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

二、中序線索化

三、中序線索二叉樹

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

五、先序線索化

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

七、後序線索化

八、後序線索化(王道教材版)

九、總結


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

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

九、總結

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