二叉樹(shù)的線索化

線索化
在二叉樹(shù)中,每個(gè)結(jié)點(diǎn)堤魁,有2個(gè)域,記為 lchild與rchild,用來(lái)記錄結(jié)點(diǎn)的左右孩子返十,如果某結(jié)點(diǎn)為葉子結(jié)點(diǎn)妥泉,或者沒(méi)有左或者右孩子,那么將用空域來(lái)表示吧慢;

在二叉樹(shù)的某個(gè)結(jié)點(diǎn)上涛漂,我們無(wú)法直接得知該結(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn)(prev)與后繼結(jié)點(diǎn)(next),只有在遍歷的時(shí)候检诗,才知道匈仗;

為了讓各結(jié)點(diǎn)鏈接起來(lái)(知道前后結(jié)點(diǎn)),同時(shí)避免空域的空間浪費(fèi)逢慌,我們?cè)诿總€(gè)結(jié)點(diǎn)上新增2個(gè)變量悠轩,lTag, rTag, 分別用來(lái)表示 lchild與rchid的指向;這樣稱為線索化攻泼;

實(shí)現(xiàn)代碼:

#include <stdio.h>
#include <stdlib.h>

typedef char ElemType;

// 線索存放標(biāo)志位火架,Link(0) : 表示指向左右孩子的指針;
//              Thread(1) : 表示指向前驅(qū)后繼的線索忙菠;
typedef enum {Link, Thread} PointerTag;

typedef struct BiThrNode {
    ElemType data;
    struct BiThrNode *lchild, *rchild;
    PointerTag ltag;
    PointerTag rtag;
} BiThrNode, *BiThrTree;

// 全局變量何鸡,記錄上次訪問(wèn)過(guò)得結(jié)點(diǎn)
BiThrTree pre;

// 創(chuàng)建一顆二叉樹(shù),按照前序遍歷的方式插入數(shù)據(jù)
void createBiThrTree(BiThrTree *T) {
    char c;
    scanf("%c",&c);
    
    if(' ' == c) {
        *T = NULL;
    } else {
        *T = (BiThrNode *)malloc(sizeof(BiThrNode));
        (*T)->data = c;
        (*T)->ltag = Link;      // 默認(rèn)有左右孩子
        (*T)->rtag = Link;
        createBiThrTree(&(*T)->lchild);
        createBiThrTree(&(*T)->rchild);
    }
}

// 中序遍歷,線索化
void inThreading(BiThrTree T) {
    if(T) {
        inThreading(T->lchild);     // 遞歸左孩子線索化
        
        // 如果該結(jié)點(diǎn)沒(méi)有左孩子牛欢,設(shè)置ltag為Thread骡男,并將lchild指向上一個(gè)訪問(wèn)的結(jié)點(diǎn)
        if(!T->lchild) {
            T->ltag = Thread;       // 線索
            T->lchild = pre;        // 指向前驅(qū)(prev)
        }
        if(!(pre->rchild)) {        // 設(shè)置后繼(next)
            pre->rtag = Thread;
            pre->rchild = T;
        }
        pre = T;                    // 記錄訪問(wèn)過(guò)的結(jié)點(diǎn)
        
        inThreading(T->rchild);     // 遞歸右孩子線索化
    }
}

// 將二叉樹(shù)線索化,建立初始化頭指針,并賦值給pre
void initInThreadingHead(BiThrTree *p, BiThrTree T) {
    *p = (BiThrTree)malloc(sizeof(BiThrNode));     // 建立頭指針傍睹,并初始化
    (*p)->ltag = Link;
    (*p)->rtag = Thread;
    (*p)->lchild = *p;      //初始化隔盛,指向自己
    
    if(!T) {
        (*p)->rchild = *p;  // 樹(shù)不存在犹菱,前驅(qū)后繼都指向自己
    } else {
        (*p)->lchild = T;
        pre = *p;
        
        inThreading(T);     // 中序線索化
        
        // 中序線索化完成后,收尾工作
        pre->rtag = Thread;
        pre->rchild = *p;
        (*p)->rchild = pre;
    }
}

void visit(char c) {
    printf("%c", c);
}

// 中序遍歷二叉樹(shù)吮炕,非遞歸腊脱,傳入頭指針
void inOrderIterator(BiThrTree T) {
    BiThrTree p;
    p = T->lchild;
    
    while(p != T) {   // 結(jié)點(diǎn)與頭指針判斷 (空樹(shù)或者遍歷結(jié)束)
        while(p->ltag == Link) {    // 左
            p = p->lchild;
        }
        visit(p->data);
        
        while(p->rtag == Thread && p->rchild != T) {           // 右,后繼
            p = p->rchild;
            visit(p->data);
        }
        
        p = p->rchild;
    }
}


//ABC__D__E_F__
int main(int argc, const char * argv[]) {
    BiThrTree P, T = NULL;
    
    createBiThrTree(&T);
    
    initInThreadingHead(&P, T);
    
    inOrderIterator(P);
    
    return 0;
}

線索化后的最終圖
紅色:后繼(next)龙亲;
藍(lán)色:前驅(qū)(prev);
新加入了頭結(jié)點(diǎn)陕凹,用來(lái)形成環(huán)

中序線索化
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俱笛,隨后出現(xiàn)的幾起案子捆姜,更是在濱河造成了極大的恐慌,老刑警劉巖迎膜,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泥技,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡磕仅,警方通過(guò)查閱死者的電腦和手機(jī)珊豹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)榕订,“玉大人店茶,你說(shuō)我怎么就攤上這事〗俸悖” “怎么了贩幻?”我有些...
    開(kāi)封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)两嘴。 經(jīng)常有香客問(wèn)我丛楚,道長(zhǎng),這世上最難降的妖魔是什么憔辫? 我笑而不...
    開(kāi)封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任趣些,我火速辦了婚禮,結(jié)果婚禮上贰您,老公的妹妹穿的比我還像新娘坏平。我一直安慰自己,他們只是感情好锦亦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布舶替。 她就那樣靜靜地躺著,像睡著了一般杠园。 火紅的嫁衣襯著肌膚如雪坎穿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天返劲,我揣著相機(jī)與錄音玲昧,去河邊找鬼。 笑死篮绿,一個(gè)胖子當(dāng)著我的面吹牛孵延,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亲配,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼尘应,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了吼虎?” 一聲冷哼從身側(cè)響起犬钢,我...
    開(kāi)封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎思灰,沒(méi)想到半個(gè)月后玷犹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洒疚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年歹颓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片油湖。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡巍扛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乏德,到底是詐尸還是另有隱情撤奸,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布喊括,位于F島的核電站胧瓜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏瘾晃。R本人自食惡果不足惜贷痪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹦误。 院中可真熱鬧劫拢,春花似錦、人聲如沸强胰。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)偶洋。三九已至熟吏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牵寺。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工悍引, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人帽氓。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓趣斤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親黎休。 傳聞我的和親對(duì)象是個(gè)殘疾皇子浓领,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 有 n 個(gè)結(jié)點(diǎn)的二叉鏈表中,其二叉鏈表的 n 個(gè)結(jié)點(diǎn)中共有 2n 個(gè)指針域势腮,在這 2n 個(gè)指針域中联贩,真正用于指向后...
    lintong閱讀 1,368評(píng)論 0 2
  • 二叉樹(shù)是非線性結(jié)構(gòu),即每個(gè)數(shù)據(jù)結(jié)點(diǎn)至多只有一個(gè)前驅(qū)捎拯,但可以有多個(gè)后繼泪幌。它可采用順序存儲(chǔ)結(jié)構(gòu)和鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。 1玄渗、順...
    文哥的學(xué)習(xí)日記閱讀 1,920評(píng)論 0 3
  • 四藤树、樹(shù)與二叉樹(shù) 1. 二叉樹(shù)的順序存儲(chǔ)結(jié)構(gòu) 二叉樹(shù)的順序存儲(chǔ)就是用數(shù)組存儲(chǔ)二叉樹(shù)浴滴。二叉樹(shù)的每個(gè)結(jié)點(diǎn)在順序存儲(chǔ)中都有...
    MinoyJet閱讀 1,528評(píng)論 0 7
  • 原鏈接:理解線索二叉樹(shù)|CloudWong 線索二叉樹(shù)原理 遍歷二叉樹(shù)的其實(shí)就是以一定規(guī)則將二叉樹(shù)中的結(jié)點(diǎn)排列成一...
    簡(jiǎn)Cloud閱讀 8,383評(píng)論 1 16
  • 第一章 緒論 什么是數(shù)據(jù)結(jié)構(gòu)? 數(shù)據(jù)結(jié)構(gòu)的定義:數(shù)據(jù)結(jié)構(gòu)是相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合岁钓。 第二章...
    SeanCheney閱讀 5,771評(píng)論 0 19