線索二叉樹(shù)

線索二叉樹(shù)實(shí)質(zhì)上就是將一顆二叉樹(shù)轉(zhuǎn)化成二叉鏈表的過(guò)程,將二叉樹(shù)的一些空指針給利用起來(lái),為了達(dá)到這個(gè)目的,我們使用中序遍歷線索化的辦法。

也就是要將每個(gè)節(jié)點(diǎn)的指針全部存儲(chǔ)一個(gè)值,為了區(qū)分線索和真正的子節(jié)點(diǎn),我們就需要一個(gè)flag,將線索和子節(jié)點(diǎn)區(qū)分開(kāi)來(lái),具體代碼如下。

#define thread 1
#define child 0

//我們將原本的節(jié)點(diǎn)擴(kuò)充一下,來(lái)區(qū)分指針存儲(chǔ)的是什么
struct treeNode
{
    int data;
    treeNode* lChild;
    treeNode* rChild;
    int lTag;
    int rTag;
};

//定義一個(gè)全局變量,指向上一次遍歷過(guò)的節(jié)點(diǎn)
//我們需要在每次遞歸線索化的時(shí)候改變這個(gè)值
//也可以不需要全局變量,改用引用
treeNode* preNode;

//中序線索化二叉樹(shù)
void cueingTree(treeNode* node)
{
    if(node != NULL)
    {
        cueingTree(node->lChild);
//如果當(dāng)前節(jié)點(diǎn)的左子樹(shù)節(jié)點(diǎn)是為NULL,則說(shuō)明它可以用來(lái)存放這個(gè)節(jié)點(diǎn)的前驅(qū)
//即上次遍歷過(guò)的節(jié)點(diǎn)
        if(node->lChild == NULL)
        {
            node->lTag = thread;
            node->lChild = preNode;
        }
//如果上個(gè)節(jié)點(diǎn)的右子樹(shù)為NULL,說(shuō)明可以存放這個(gè)節(jié)點(diǎn)的后繼
//只有在知道了后繼之后才能為前一個(gè)節(jié)點(diǎn)賦值
        if(preNode->rChild == NULL)
        {
            preNode->rTag = thread;
            preNode->rChild = node;
        }
//更新上次遍歷過(guò)的節(jié)點(diǎn)
        preNode = node;
        if(node->rChild != node)
        {
            cueingTree(node->rChild);
        }
    }
}

//在有了線索二叉樹(shù)之后,我們便可以使用迭代的方式來(lái)遍歷二叉樹(shù)
void inOrderTraversal()
{
    treeNode* currentNode = this->head->lChild;
    while(currentNode != this->head)
    {
        while(currentNode->lTag == child)
        {
            currentNode = currentNode->lChild;
        }
        cout << currentNode->data << "  ";
        while(currentNode->rTag == thread && currentNode->rChild != this->head)
        {
            currentNode = currentNode->rChild;
            cout << currentNode->data << "  ";
        }
        currentNode = currentNode->rChild;
    }
}

其實(shí)線索二叉樹(shù)的建立過(guò)程,就是一次中序遍歷的過(guò)程,在遍歷過(guò)程中,對(duì)每一個(gè)節(jié)點(diǎn)進(jìn)行線索化,如果有能利用到的空指針,就可以用來(lái)存放前驅(qū)后繼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 原鏈接:理解線索二叉樹(shù)|CloudWong 線索二叉樹(shù)原理 遍歷二叉樹(shù)的其實(shí)就是以一定規(guī)則將二叉樹(shù)中的結(jié)點(diǎn)排列成一...
    簡(jiǎn)Cloud閱讀 8,432評(píng)論 1 16
  • 數(shù)據(jù)結(jié)構(gòu)與算法--線索二叉樹(shù)及其前序、中序遍歷 二叉樹(shù)如果某個(gè)結(jié)點(diǎn)沒(méi)有左孩子或右孩子,則這個(gè)域就為空。如node....
    sunhaiyu閱讀 2,764評(píng)論 4 16
  • 線索二叉樹(shù)的原理 通過(guò)考察各種二叉鏈表,不管兒叉樹(shù)的形態(tài)如何,空鏈域的個(gè)數(shù)總是多過(guò)非空鏈域的個(gè)數(shù)。準(zhǔn)確的說(shuō),n各結(jié)...
    葛高召閱讀 742評(píng)論 0 0
  • 線索二叉樹(shù)的原理 通過(guò)考察各種二叉鏈表,不管兒叉樹(shù)的形態(tài)如何,空鏈域的個(gè)數(shù)總是多過(guò)非空鏈域的個(gè)數(shù)。準(zhǔn)確的說(shuō),n各結(jié)...
    Gaizka閱讀 584評(píng)論 0 0
  • 線索二叉樹(shù)的原理 通過(guò)考察各種二叉鏈表,不管兒叉樹(shù)的形態(tài)如何,空鏈域的個(gè)數(shù)總是多過(guò)非空鏈域的個(gè)數(shù)。準(zhǔn)確的說(shuō),n各結(jié)...
    少帥yangjie閱讀 337評(píng)論 0 1