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

来源:互联网 发布:unity3d制作2d游戏教程 编辑:程序博客网 时间:2024/05/16 00:33

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

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

#include <iostream>#include <windows.h>#include <string.h>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<T>* _pLeft;    BinaryTreeNodeThd<T>* _pRight;    BinaryTreeNodeThd<T>* _pParent;    PointIhfo _leftThread;    PointIhfo _rightTrhead;};

这里写图片描述

template<class T>class BinaryTreeThd{    typedef BinaryTreeNodeThd<T> 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<T>& bt)    {        _pRoot = _CopyBinaryTree(bt._pRoot);    }    BinaryTreeThd<T>& operator=(const BinaryTreeThd<T>& 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<<pCur->_value<<" ";                pCur = pCur->_pLeft;            }            cout<<pCur->_value<<" ";//访问最左边的节点            while(pCur->_rightTrhead == THREAD)//如果该结点没有右孩子,则一直访问            {                pCur = pCur->_pRight;                cout<<pCur->_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<<pCur->_value<<" ";//访问最左结点            while(pCur->_rightTrhead == THREAD)//如果该结点没有右孩子,则一直访问该节点            {                pCur = pCur->_pRight;                cout<<pCur->_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<<pCur->_value<<" ";                pPre = pCur;                 //将当前节点保存                pCur = pCur->_pRight;            }            while(pCur && pCur->_pRight == pPre)  //如果当前节点的右孩子刚刚被访问,就访问当前节点            {                cout<<pCur->_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<size && arr[index] != invalid)        {            //创建根节点            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<char> bt2(bt1);    system("pause");    return 0;}
0 0
原创粉丝点击