線索二叉樹的生成及遍歷

概念

線索二叉樹:按照某種遍歷方式對二叉樹進行遍歷,可以把二叉樹中所有結點排序爲一個線性序列。在改序列中,除第一個結點外每個結點有且僅有一個直接前驅結點;除最後一個結點外每一個結點有且僅有一個直接後繼結點。這些指向直接前驅結點和指向直接後續結點的指針被稱爲線索(Thread),加了線索的二叉樹稱爲線索二叉樹。

百科解釋:鏈接


完整C++代碼:

#include <iostream>
using namespace std;

//線索二叉樹的鏈式儲存結構 
typedef struct BiThrNode
{
    char ch;    // 數據 
    struct BiThrNode *lChild, *rChild;    // 左右子樹 
    bool LTag, RTag;    //左右線索標誌 
}BiThrNode, *BiThrTree;

BiThrTree pre;    // 前驅節點,用來生成線索二叉樹 

/*
* 創建一個二叉樹節點 
* 返回創建的新節點 
*/
BiThrTree CreateBiThrNode(char ch)
{
    BiThrTree newT = new BiThrNode;
    newT->ch = ch;
    newT->lChild = newT->rChild = NULL;
    newT->LTag = newT->RTag = false;
    return newT;
}

/*
* 創建二叉樹 
* 根據輸入先序創建二叉樹, 輸入 # 表示爲空樹 
*/
void CreateBiThrTree(BiThrTree &rootT)
{
    char ch;
    cin >> ch;
    if('#' == ch){
        rootT = NULL;
    }
    else{
        rootT = CreateBiThrNode(ch);
        CreateBiThrTree(rootT->lChild);
        CreateBiThrTree(rootT->rChild);
    }
}

/*
* 二叉樹的中序線索化 
* 中序遍歷依次改寫指針 
*/
void InThreading(BiThrTree rootT)
{
    if(rootT){
        InThreading(rootT->lChild);    //線索化左子樹 

        // 改寫左線索指針 
        if(rootT->lChild == NULL){
            rootT->LTag = true;
            rootT->lChild = pre;
        }else{
            rootT->LTag = false;
        }

        // 改寫右線索指針 
        if(pre->rChild == NULL){
            pre->RTag = true;
            pre->rChild = rootT;
        }else{
            pre->RTag = false;
        }

        pre = rootT;    // 記錄前驅節點 
        InThreading(rootT->rChild);    // 線索化右子樹 
    }
}

/*
* 二叉樹的中序線索化 
* 返回頭節點
*/
BiThrTree InOrderThreading(BiThrTree rootT)
{
    BiThrTree firstT = CreateBiThrNode('#');
    firstT->LTag = false;
    firstT->RTag = true;

    if(rootT == NULL){
        firstT->rChild = firstT;    // 樹爲空,則右線索指向自己 
    }else{
        firstT->lChild = rootT;    // 左線索指向樹根節點 

        pre = firstT;
        InThreading(rootT);

        // 最後節點的右線索指針指向頭節點 
        pre->rChild = firstT;
        pre->RTag = true;

        firstT->rChild = pre;   // 右線索指向最後訪問的節點 
    }

    return firstT;
}

/*
* 中序遍歷線索二叉樹  
* 重複:輸出節點數據,獲取後繼節點
*/ 
void InOder_Traverse_Thr(BiThrTree firstT)
{
    BiThrTree pT = firstT->lChild;    //獲取根節點 
    while(pT != firstT){
        // 沿左孩向子下 
        while(! pT->LTag){
            pT = pT->lChild;
        }

        cout << pT->ch << " ";

        // 沿右線索訪問後繼節點 
        while(pT->RTag && pT->rChild != firstT){
            pT = pT->rChild;
            cout << pT->ch << " ";
        }
        pT = pT->rChild;    // 轉向右子樹 
    }
}

int main()
{
    BiThrTree rootT;
    CreateBiThrTree(rootT);
    BiThrTree firstT = InOrderThreading(rootT);
    InOder_Traverse_Thr(firstT);
    return 0;
}

銷燬的操作沒有寫,但對於這個程序,這點內存泄露也沒什麼影響(^_^)
這裏只給出了中序線索化及遍歷方法,其它的就不寫了(^_^)

參考博文:http://blog.csdn.net/jiajiayouba/article/details/9224403


運行結果

這裏寫圖片描述

這裏寫圖片描述


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