线索化二叉树(前序线索化,中序线索化)

为什么要对二叉树进行线索化?

对二叉树进行遍历是以一定的规则将二叉树的节点排列成一个线性序列,这些线性序列有且仅有一个直接前驱和直接后继,但是以二叉链表进行存储的时候,只能找到节点的左右孩子信息,不能直接得到节点在任一序列的前驱和后继信息,前驱和后继信息只能在遍历的动态过程中才能得到。

如何获取到前驱和后继的信息呢?

在有n个节点的二叉链表中必定存在n+1个空链域,利用这些空链域存放节点的前驱和后继信息,所以在每个节点上增加两个指针域分别指向节点在任一序列中的前驱和后继信息。

节点结构:

《线索化二叉树(前序线索化,中序线索化)》

以上述节点结构构成的二叉链表作为二叉链表的存储结构,叫做线索化链表;
指向节点前驱和后继的指针称为线索;
加上线索的二叉树称为线索二叉树;
对二叉树以某种次序遍历使其成为线索二叉树的过程称为线索化。

线索化的总思路:如果访问到当前节点的时候,线索化其左子树并记录下上一个访问的节点;再对上一个访问的节点的右子树进行线索化,直到所有节点都访问完。

前序线索化:

《线索化二叉树(前序线索化,中序线索化)》

//prev需要传引用进去,才能记录下上次访问的节点,否则节点的右子树的线索化不能完成
void _PrevOrder_Th(Node* root, Node*& prev)
    {
        if (root == NULL)
        {
            return;
        }
        if (root->_LeftNode == NULL)
        {
            root->_LeftNode = prev;
            root->LeftTag = THREAD;
        }
        if (prev&&prev->_RightNode == NULL)
        {
            prev->_RightNode = root;
            prev->RightTag = THREAD;
        }

        prev = root;
        if (root->LeftTag == LINK)
        {
            _PrevOrder_Th(root->_LeftNode, prev);
        }
        if (root->RightTag == LINK)
        {
            _PrevOrder_Th(root->_RightNode, prev);
        }
    }

前序线索化的遍历:
遇到先对其进行进行访问,再对其左子树进行遍历访问,直到找到最左的那个节点;再根据线索化的指向对其右子树进行遍历访问。

void PreOrder()
    {
        Node* cur = _root;
        while (cur)
        {
            while (cur->LeftTag == LINK)
            {
                cout << cur->_data<<" ";
                cur = cur->_LeftNode;
            }
            cout << cur->_data<<" ";
            cur = cur->_RightNode;
        }
        cout << endl;
    }

中序线索化:

《线索化二叉树(前序线索化,中序线索化)》

void _InOrder_Th(Node* root, Node*& prev)
    {
        if (root == NULL)
        {
            return;
        }
        else
        {
            _InOrder_Th(root->_LeftNode, prev);
            if (root->_LeftNode == NULL)
            {
                root->_LeftNode = prev;
                root->LeftTag = THREAD;
            }
            if (prev&&prev->_RightNode == NULL)
            {
                prev->_RightNode = root;
                prev->RightTag = THREAD;
            }
            prev = root;
            _InOrder_Th(root->_RightNode, prev);
        }
    }

中序线索化的遍历:

void InOrder()
    {
        Node* cur = _root;

        while (cur)
        {
            //找到最左的点
            while (cur->LeftTag == LINK)
            {
                cur = cur->_LeftNode;
            }
            cout << cur->_data << " ";
            while (cur->RightTag == THREAD)
            {
                cur = cur->_RightNode;
                cout << cur->_data << " ";
            }
            cur = cur->_RightNode;
        }   
        cout << endl;
    }
    原文作者:Emily静
    原文地址: https://blog.csdn.net/qq_39295755/article/details/79535406
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞