二叉树的线索化和遍历

包括二叉树的前序,中序,后序线索化和线索化遍历

#pragma once

#include<iostream>
using namespace std;

enum pInfo{ LINK, THREAD };

template<class T>
struct BinTreeThreadNode
{
    BinTreeThreadNode(const T data)
    :_pLeft(NULL)
    , _pRight(NULL)
    , _pParent(NULL)
    , _data(data)
    , _pLeftThread(LINK)
    , _pRightThread(LINK)
    {}

    BinTreeThreadNode<T>* _pLeft;
    BinTreeThreadNode<T>* _pRight;
    BinTreeThreadNode<T>* _pParent;
    T _data;
    pInfo _pLeftThread;
    pInfo _pRightThread;
};

template <class T>
class BinTreeThread
{
    typedef BinTreeThreadNode<T> Node;
    typedef Node* pNode;
    typedef void(*pFun)(pNode);

public:
    BinTreeThread()
        :_pRoot(NULL)
    {}
    void CreateBinTree(T* arr, size_t size, T invalid)
    {
        size_t index = 0;
        _CreateBinTree(_pRoot, arr, size, index, invalid);
    }
    void PreVisit()//前序遍历
    {
        _PreVisit(_pRoot, _PrintNode);
    }

    void InVisit()//中序遍历
    {
        _InVisit(_pRoot, _PrintNode);
    }

    void PostVisit()//后序遍历
    {
        _PostVisit(_pRoot, _PrintNode);
    }

    void LevelVisit()//层序遍历
    {
        _LevelVisit(_pRoot, _PrintNode);
    }

    void PreThread()
    {
        pNode prev = NULL;
        _PreThread(_pRoot,prev);
    }

    void InThread()
    {
        pNode prev = NULL;
        _InThread(_pRoot,prev);
    }

    void PostThread()
    {
        pNode prev = NULL;
        _PostThread(_pRoot,prev);
    }

    void PreThreadVisit()
    {
        _PreThreadVisit(_pRoot,_PrintNode);
    }

    void InThreadVisit()
    {
        _InThreadVisit(_pRoot,_PrintNode);
    }

    void PostThreadVisit()
    {
        _PostThreadVisit(_pRoot,_PrintNode);
    }
protected:

    void _CreateBinTree(pNode& root, T* arr, size_t size, size_t& index, T invalid)
    {
        if (index < size && invalid != arr[index])
        {
            root = new Node(arr[index]);

            _CreateBinTree(root->_pLeft, arr, size, ++index, invalid);

            if (root->_pLeft)
                root->_pLeft->_pParent = root;
            _CreateBinTree(root->_pRight, arr, size, ++index, invalid);

            if (root->_pRight)
                root->_pRight->_pParent = root;
        }
        else
            root = NULL;
    }

    void _PreVisit(pNode& pd, pFun visit)
    {
        if (pd)
        {
            visit(pd);
            if (pd->_pLeft)
                _PreVisit(pd->_pLeft, visit);
            if (pd->_pRight)
                _PreVisit(pd->_pRight, visit);
        }
    }

    void _InVisit(pNode& pd, pFun visit)
    {
        if (pd)
        {
            if (pd->_pLeft)
                _InVisit(pd->_pLeft, visit);
            visit(pd);
            if (pd->_pRight)
                _InVisit(pd->_pRight, visit);
        }
    }

    void _PostVisit(pNode& pd, pFun visit)
    {
        if (pd)
        {
            if (pd->_pLeft)
                _PostVisit(pd->_pLeft, visit);
            if (pd->_pRight)
                _PostVisit(pd->_pRight, visit);
            visit(pd);
        }
    }

    void _LevelVisit(pNode& pd, pFun visit)
    {
        if (NULL == _pRoot)
            return;
        queue<pNode> q;
        pNode pCur = pd;
        q.push(pd);
        while (!q.empty())
        {
            pCur = q.front();
            visit(pCur);
            if (pCur->_pLeft)
                q.push(pCur->_pLeft);
            if (pCur->_pRight)
                q.push(pCur->_pRight);
            q.pop();
        }
    }

    static void _PrintNode(pNode pd)
    {
        cout << pd->_data << "->";
    }

    void _PreThread(pNode& pd, pNode& prev)
    {
        if (NULL == pd)
            return;

        //线索化当前节点
        if (NULL == pd->_pLeft)
        {
            pd->_pLeft = prev;
            pd->_pLeftThread = THREAD;
        }
        if (prev && NULL == prev->_pRight)
        {
            prev->_pRight = pd;
            prev->_pRightThread = THREAD;
        }
        prev = pd;

        //线索化左子树
        if (LINK == pd->_pLeftThread)
            _PreThread(pd->_pLeft,prev);

        //线索化右子树
        if (LINK == pd->_pRightThread)
            _PreThread(pd->_pRight,prev);       
    }

    void _InThread(pNode& pd, pNode& prev)
    {
        if (NULL == pd)
            return;

        _InThread(pd->_pLeft,prev);

        if (NULL == pd->_pLeft)
        {
            pd->_pLeft = prev;
            pd->_pLeftThread = THREAD;
        }
        if (prev && NULL == prev->_pRight)
        {
            prev->_pRight = pd;
            prev->_pRightThread = THREAD;
        }
        prev = pd;

        if (LINK == pd->_pRightThread)
            _InThread(pd->_pRight,prev);
    }

    void _PostThread(pNode& pd, pNode& prev)
    {
        if (NULL == pd)
            return;

        _PostThread(pd->_pLeft, prev);
        _PostThread(pd->_pRight, prev);

        if (NULL == pd->_pLeft)
        {
            pd->_pLeft = prev;
            pd->_pLeftThread = THREAD;
        }
        if (prev && NULL == prev->_pRight)
        {
            prev->_pRight = pd;
            prev->_pRightThread = THREAD;
        }
        prev = pd;  
    }

    void _PreThreadVisit(pNode pd, pFun visit)
    {
        if (NULL == pd)
            return;
        pNode pCur = pd;

        while (pCur)
        {
            while (LINK == pCur->_pLeftThread)
            {
                visit(pCur);
                pCur = pCur->_pLeft;
            }
            visit(pCur);
            pCur = pCur->_pRight;
        }
    }

    void _InThreadVisit(pNode pd, pFun visit)
    {
        if (NULL == pd)
            return;

        pNode pCur = pd;

        while (pCur)
        {
            while (LINK == pCur->_pLeftThread)
                pCur = pCur->_pLeft;
            visit(pCur);
            while (pCur && THREAD == pCur->_pRightThread)
            {
                pCur = pCur->_pRight;
                visit(pCur);
            }

            pCur = pCur->_pRight;
        }
    }

    void _PostThreadVisit(pNode pd, pFun visit)
    {
        if (NULL == pd)
            return;

        pNode pCur = pd;
        pNode prev = NULL;
        while (pCur)
        {
            //找到最左边的节点
            while (prev != pCur->_pLeft && LINK == pCur->_pLeftThread)
                pCur = pCur->_pLeft;

            while (pCur && THREAD == pCur->_pRightThread)
            {
                visit(pCur);
                prev = pCur;
                pCur = pCur->_pRight;
            }

            if (pCur == pd && (prev == pd->_pRight || NULL == pd->_pRight))
            {
                visit(pCur);
                return;
            }

            while (pCur&& prev == pCur->_pRight)
            {
                visit(pCur);
                prev = pCur;
                pCur = pCur->_pParent;
            }

            if (pCur && LINK == pCur->_pRightThread)
                pCur = pCur->_pRight;
        }
    }


private:
    pNode _pRoot;
};


void TestBinTreeThread()
{
    BinTreeThread<char> bt;
    char arr[] = "ABD###CE##F";/*
                                A
                               / \
                              B   C
                             /    /\
                            D    E  F
                               */
    bt.CreateBinTree(arr, strlen(arr), '#');//创建树
    //bt.PreVisit();
    //bt.PreThread();
    //cout << endl;
    /*bt.InVisit();
    bt.InThread();*/
    //bt.PostThread();
    //bt.PreThreadVisit();


    /*cout << endl;
    bt.InThreadVisit();*/

    bt.PostVisit();
    cout << endl;
    bt.PostThread();
    bt.PostThreadVisit();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值