线索二叉树的先序、中序、后序遍历

线索化二叉树:
当某个节点的左孩子为空时,将_pLeft指针指向他的前一个节点;
当某个节点的右孩子为空时,将_pRight指针指向它的后一个结点。

根据遍历方式不同,得到的前后节点也不同,线索化二叉树分为三种不同的情况:
先序遍历线索化二叉树
中序遍历线索化二叉树
后序遍历线索化二叉树
线索二叉树与普通二叉树有什么区别呢?线索化二叉树中空的指针域至多2个,至少1个;
普通二叉树中空的指针域是n+1个,n(节点数)。
所以能够有效地利用资源,并且在遍历时不用递归和栈结构也可以遍历。
为了区别两个节点的关系是双亲-孩子节点,还是前驱-后继节点,可以在每个节点创建时 ,增加两个成员变量,_leftThread和_rightThread,这两个变量只有两种状态,LINK(双亲-孩子)、THREAD(前驱=后继)。

#include 
#include 
#include 
using namespace std;
enum PointIhfo
{
    LINK, 
    THREAD
};
template <class T>
struct BinaryTreeNodeThd//定义二叉树的节点
{
    BinaryTreeNodeThd(const T& value)
        :_value(value)
        ,_pLeft(NULL)
        ,_pRight(NULL)
        ,_pParent(NULL)
        , _leftThread(LINK)
        , _rightTrhead(LINK)
    {}
    T _value;
    BinaryTreeNodeThd* _pLeft;
    BinaryTreeNodeThd* _pRight;
    BinaryTreeNodeThd* _pParent;
    PointIhfo _leftThread;
    PointIhfo _rightTrhead;
};

线索二叉树的先序、中序、后序遍历_第1张图片

template
class BinaryTreeThd
{
    typedef BinaryTreeNodeThd Node;
public:
    BinaryTreeThd()
        :_pRoot(NULL)
    {}
    BinaryTreeThd(const T arr[], size_t size, const T& invalid)
    {
        size_t index=0;
        _CreateBinaryTree(_pRoot, NULL, arr, size, index, invalid);
    }
    BinaryTreeThd(const BinaryTreeThd& bt)
    {
        _pRoot = _CopyBinaryTree(bt._pRoot);
    }
    BinaryTreeThd& operator=(const BinaryTreeThd& bt)
    {
        if(this != &bt)
        {
            _DestroyBinaryTree(_pRoot);
            _pRoot = _CopyBinaryTree(bt._pRoot);
        }
        return *this;
    }
    ~BinaryTreeThd()
    {
        _DestroyBinaryTree(_pRoot);
    }
    void PreThread()
    {
        Node* prev = NULL;
        _PreThread(_pRoot, prev);
    }
    void InThread()
    {
        Node* prev = NULL;
        _InThread(_pRoot, prev);
    }
    void PostThread()
    {
        Node* prev = NULL;
        _PostThread(_pRoot, prev);
    }
    void PreOrder()
    {
        if(_pRoot == NULL)
            return;
        Node* pCur = _pRoot;
        while(pCur)
        {
            while(pCur->_leftThread == LINK)//访问到最左结点
            {
                cout<_value<<" ";
                pCur = pCur->_pLeft;
            }
            cout<_value<<" ";//访问最左边的节点
            while(pCur->_rightTrhead == THREAD)//如果该结点没有右孩子,则一直访问
            {
                pCur = pCur->_pRight;
                cout<_value<<" ";
            }
            if(pCur->_leftThread == LINK)//如果该结点有左孩子,则访问左孩子
                pCur = pCur->_pLeft;
            else                         //否则访问右孩子
                pCur = pCur->_pRight;
        }
    }
    void InOrder()
    {
        if(_pRoot == NULL)
            return;
        Node* pCur = _pRoot;
        while(pCur)
        {
            while(pCur->_leftThread == LINK)//找最左节点
                pCur = pCur->_pLeft;
            cout<_value<<" ";//访问最左结点
            while(pCur->_rightTrhead == THREAD)//如果该结点没有右孩子,则一直访问该节点
            {
                pCur = pCur->_pRight;
                cout<_value<<" ";
            }
            pCur = pCur->_pRight;//如果该结点有右孩子,则访问右孩子
        }
    }
    void PostOrder()
    {
        if(_pRoot == NULL)
            return;
        Node* pCur = _pRoot;
        Node* pPre = NULL;
        while(pCur)
        {
            while(pCur->_leftThread == LINK)//找到最左结点
                pCur = pCur->_pLeft;
            while(pCur && pCur->_rightTrhead == THREAD)//如果最左结点存在且它的右孩子
            {                                        //不存在,就一直访问它的右孩子
                cout<_value<<" ";
                pPre = pCur;                 //将当前节点保存
                pCur = pCur->_pRight;
            }
            while(pCur && pCur->_pRight == pPre)  //如果当前节点的右孩子刚刚被访问,就访问当前节点
            {
                cout<_value<<" ";
                pPre = pCur;
                pCur = pCur->_pParent;
            }
            if(pCur && pCur->_rightTrhead == LINK)//如果当前节点的右孩子存在,就访问它的右孩子
                pCur = pCur->_pRight;
        }
    }
private:
    void _CreateBinaryTree(Node* &pRoot, Node* pParent, const T arr[], size_t size, size_t& index, const T& invalid)
    {
        if(index//创建根节点
            pRoot = new Node(arr[index]);
            pRoot->_pParent = pParent;
            //创建左子树
            _CreateBinaryTree(pRoot->_pLeft, pRoot, arr, size, ++index, invalid);
            pRoot->_leftThread = LINK;
            //创建右子树
            _CreateBinaryTree(pRoot->_pRight, pRoot, arr, size, ++index, invalid);
            pRoot->_rightTrhead = LINK;
        }
    }
    Node* _CopyBinaryTree(Node* pRoot)
    {
        Node* pNode = NULL;
        if(pRoot)
        {
            pNode = new Node(pRoot->_value);
            pNode->_pLeft = _CopyBinaryTree(pRoot->_pLeft);
            pNode->_leftThread = pRoot->_leftThread;
            pNode->_pParent = pRoot->_pParent;
            pNode->_pRight = _CopyBinaryTree(pRoot->_pRight);
            pNode->_rightTrhead = pRoot->_rightTrhead;
            pNode->_pParent = pRoot->_pParent;
        }
        return pNode;
    }
    void _DestroyBinaryTree(Node*& pRoot)
    {
        if(pRoot)
        {
            _DestroyBinaryTree(pRoot->_pLeft);
            _DestroyBinaryTree(pRoot->_pRight);
            delete pRoot;
            pRoot = NULL;
        }
    }
    void _PreThread(Node* pRoot, Node*& prev)
    {
        if(pRoot == NULL)
            return;
        if(pRoot->_pLeft == NULL)
        {
            pRoot->_pLeft = prev;
            pRoot->_leftThread = THREAD;
        }
        if(prev && prev->_pRight == NULL)
        {
            prev->_pRight = pRoot;
            prev->_rightTrhead = THREAD;
        }
        prev = pRoot;
        if(pRoot->_leftThread == LINK)
            _PreThread(pRoot->_pLeft, prev);
        if(pRoot->_rightTrhead == LINK)
            _PreThread(pRoot->_pRight, prev);
    }
    void _InThread(Node* pRoot, Node*& prev)
    {
        if(pRoot == NULL)
            return;
        //左子树
        if(pRoot->_leftThread == LINK)
            _InThread(pRoot->_pLeft, prev);
        if(pRoot->_pLeft == NULL)
        {
            pRoot->_pLeft = prev;
            pRoot->_leftThread = THREAD;
        }
        if(prev && prev->_pRight == NULL)
        {
            prev->_pRight = pRoot;
            prev->_rightTrhead = THREAD;
        }
        prev = pRoot;
        //右子树
        if(pRoot->_rightTrhead == LINK)
            _InThread(pRoot->_pRight, prev);
    }
    void _PostThread(Node* pRoot, Node*& prev)
    {
        if(pRoot == NULL)
            return;
        //左子树
        if(pRoot->_leftThread == LINK)
            _PostThread(pRoot->_pLeft, prev);
        //右子树
        if(pRoot->_rightTrhead == LINK)
            _PostThread(pRoot->_pRight, prev);
        if(pRoot->_pLeft == NULL)
        {
            pRoot->_pLeft = prev;
            pRoot->_leftThread = THREAD;
        }
        if(prev && prev->_pRight == NULL)
        {
            prev->_pRight = pRoot;
            prev->_rightTrhead = THREAD;
        }
        prev = pRoot;
    }
private:
    Node* _pRoot;//根节点
};
int main()
{
    char* arr = "124##5##3#6";
    BinaryTreeThd<char> bt1(arr, strlen(arr), '#');
    //bt1.PreThread();
    //bt1.PreOrder();
    //bt1.InThread();
    //bt1.InOrder();
    bt1.PostThread();
    bt1.PostOrder();
    //BinaryTreeThd bt2(bt1);
    system("pause");
    return 0;
}

你可能感兴趣的:(数据结构)