zoukankan      html  css  js  c++  java
  • 二叉查找树的前序遍历,后序遍历和中序遍历互求算法模板

    遍历模板


    其实这个问题想清楚了很简单,只要把这三个概念理解透彻就可以做出来了,比如前序遍历的第一个值一定是根节点,然后这个根节点对应到中序遍历里面,在中序遍历的这个值的两边的值,一定在以此节点为根节点的两个子树上,同理,后序遍历也一样。

    已知前序遍历和后序遍历是不能求唯一的中序遍历树的。

     

    #include <iostream>
    #include <string>
    
    using std::string;
    
    template<typename _Val>
    struct TreeNodeBase
    {
        TreeNodeBase<_Val> *left;
        TreeNodeBase<_Val> *right;
        _Val val;
    };
    
    //已知前序遍历和中序遍历,找后序遍历
    template<typename _Iter, typename _sizeType, typename _TreeNodeType = TreeNodeBase<char>>
    _TreeNodeType *preOrderInfixOrderToSufixOrder(_Iter &pre, _Iter &in, _sizeType length)
    {
        if (length == 0)
            return nullptr;
    
        auto node = new _TreeNodeType;
        
        _sizeType index = 0;
    
        for (; index != length; index++)//找到对应的前序遍历的点
            if (*(in + index) == *(pre))
                break;
    
        node->left = preOrderInfixOrderToSufixOrder(pre + 1, in, index);
        node->right = preOrderInfixOrderToSufixOrder(pre + index + 1, in + index + 1, length - (index + 1));
        node->val = *pre;
        std::cout << node->val << " ";
        return node;
    }
    
    //已知后序遍历和中序遍历,找前序遍历
    template<typename _Iter, typename _sizeType, typename _TreeNodeType = TreeNodeBase<char>>
    _TreeNodeType *sufixOrderInfixOrderToPreOrder(_Iter &sufix, _Iter &in, _sizeType length)
    {
        if (length == 0)
            return nullptr;
        auto node = new _TreeNodeType;
        node->val = *(sufix + length - 1);
        std::cout << node->val << " ";
    
        _sizeType index = 0;
        for (;index != length ;index++)
            if (*(in + index) == *(sufix + length - 1))
                break;
        node->left = sufixOrderInfixOrderToPreOrder(sufix, in, index);
        node->right = sufixOrderInfixOrderToPreOrder(sufix + index, in + index + 1, length - (index + 1));
    
        return node;
    }
    
    //已知前序遍历/后序遍历 + 中序遍历求后序遍历/前序遍历
    /*int main()
    {
        string preOrder("GDAFEMHZ");
        string infixOrder("ADEFGHMZ");
        string sufixOrder("AEFDHZMG");
    
        auto root1 = preOrderInfixOrderToSufixOrder(preOrder.begin(), infixOrder.begin(), preOrder.size());
        std::cout << std::endl;
        auto root2 = sufixOrderInfixOrderToPreOrder(sufixOrder.begin(), infixOrder.begin(), preOrder.size());
    
        system("pause");
        return 0;
    }*/

     

    线索二叉树与前序遍历,后序遍历,中序遍历的联系


    线索二叉树是利用了二叉树中的null节点,在遍历二叉树时,如果我们要找一个子节点的前继和后序,往往我们只能通过递归的方法,但是用了线索二叉树以后就不用了,直接while循环就可以了(注意后序线索二叉树不可以,必须要辅助栈)

    写了个C++模板来玩:

        typedef enum { Node, Thread } ChildType;
    
        struct __trueType{ };
        struct __falseType { };
    
        template<typename _Val>
        struct TreeNodeBase
        {
            typedef __falseType __isThreadingTree;
            TreeNodeBase() 
                :left(nullptr), right(nullptr), val(0) { }
            _Val val;
    
            void *left, *right;
            virtual ~TreeNodeBase() { }
        };
    
        template<typename _Val>
        struct ThreadingTreeNodeBase :public TreeNodeBase<_Val>
        {
            typedef __trueType __isThreadingTree;
            ThreadingTreeNodeBase()
                :leftType(ChildType::Node),rightType(ChildType::Node){ }
    
            ThreadingTreeNodeBase<_Val> *left;
            ThreadingTreeNodeBase<_Val> *right;
            ChildType leftType, rightType;
            ~ThreadingTreeNodeBase() { }
        };
    
        template<typename _TnBase>
        class TreeHelper final
        {
        public:
            inline static void createInOrderThreadingTree(_TnBase *root);
            inline static void createPreOrderThreadingTree(_TnBase *root);
            inline static void createSufixOrderThreadingTree(_TnBase *root);
    
            static void inOrderShow(std::ostream &os, _TnBase *root);
            static void preOrderShow(std::ostream &os, _TnBase *root);
            static void sufixOrderShow(std::ostream &os, _TnBase *const root);
    
            template<typename _Iter, typename _sizeType>
            inline static _TnBase *preOrderInfixOrderToSufixOrder(_Iter &pre, _Iter &in, _sizeType length);
    
            static void setOstream(std::ostream &os) { _os = os; }
            static std::ostream &getOstream() { return _os; }
        private:
            template<typename _Iter, typename _sizeType>
            inline static _TnBase *preOrderInfixOrderToSufixOrderPirvate(_Iter &pre, _Iter &in, _sizeType length, __trueType);
            template<typename _Iter, typename _sizeType>
            static _TnBase *preOrderInfixOrderToSufixOrderPirvate1(_Iter &pre, _Iter &in, _sizeType length, __trueType);
    
            template<typename _Iter, typename _sizeType>
            inline static _TnBase *preOrderInfixOrderToSufixOrderPirvate(_Iter &pre, _Iter &in, _sizeType length, __falseType);
            template<typename _Iter, typename _sizeType>
            static _TnBase *preOrderInfixOrderToSufixOrderPirvate1(_Iter &pre, _Iter &in, _sizeType length, __falseType);
    
            static void createInOrderThreadingTreePrivate(_TnBase *root, _TnBase *&_preNode);
            static void createPreOrderThreadingTreePrivate(_TnBase *root, _TnBase *&_preNode);
            static void createSufixOrderThreadingTreePrivate(_TnBase *root, _TnBase *&_preNode);
    
            static _TnBase *_preNode;
            static std::ostream &_os;
    
            static void clearNodeType(_TnBase *root);
    
            TreeHelper() = delete;
            TreeHelper(const TreeHelper< _TnBase> &) = delete;
            TreeHelper(TreeHelper< _TnBase> &&) = delete;
        };
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::inOrderShow(std::ostream &os, _TnBase *root)
        {
            if (root == nullptr)
                return;
    
            while (root)
            {
                while (root->leftType == ChildType::Node)
                    root = reinterpret_cast<_TnBase *>(root->left);
                while (root != nullptr)
                {
                    os << root->val << " ";
                    if (root->rightType == ChildType::Thread)
                        root = reinterpret_cast<_TnBase *>(root->right);
                    else
                    {
                        root = reinterpret_cast<_TnBase *>(root->right);
                        while (root->leftType == ChildType::Node)
                            root = reinterpret_cast<_TnBase *>(root->left);
                    }
                }
            }
        }
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::preOrderShow(std::ostream &os, _TnBase *root)
        {
            if (root == nullptr)
                return;
    
            while (root)
            {
                while (root != nullptr)
                {
                    os << root->val << " ";
                    if (root->rightType == ChildType::Thread)
                        root = reinterpret_cast<_TnBase *>(root->right);
                    else
                        root = root->leftType == ChildType::Node ? 
                        reinterpret_cast<_TnBase *>(root->left) : reinterpret_cast<_TnBase *>(root->right);
                }
            }
        }
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::sufixOrderShow(std::ostream &os, _TnBase *const root)
        {
            //注意:后序遍历不能真正通过线索走完所有节点,要用栈
            if (root == nullptr)
                return;
    
            _TnBase *p = root;
    
            using std::stack;
            stack<_TnBase *> s;
    
            _TnBase *pre = nullptr;
    
            while (true)
            {
                while (p->leftType != ChildType::Thread)
                {
                    if (p->leftType == ChildType::Node &&  p->rightType == ChildType::Node)
                        s.push(p);
                    p = reinterpret_cast<_TnBase *>(p->left);
                }
    
                //pre节点跟踪右节点的情况
                while (p && p->rightType == ChildType::Thread)
                {
                    os << p->val << " ";
                    pre = reinterpret_cast<_TnBase *>(p);
                    p = reinterpret_cast<_TnBase *>(p->right);
                }
                    
                while (p->right == pre && !s.empty())
                {
                    os << p->val << " ";
                    pre = p;
                    s.pop();
                    if (!s.empty())
                        p = s.top();
                }
                if (s.empty())
                    break;
    
                if (p != nullptr && p->rightType != ChildType::Thread)
                    p = reinterpret_cast<_TnBase *>(p->right);
            }
    
        }
    
        template<typename _TnBase> std::ostream &TreeHelper<_TnBase>::_os = std::cout;
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::clearNodeType(_TnBase *root)
        {
            if (root->leftType == ChildType::Thread)
            {
                root->leftType = ChildType::Node;
                root->left = nullptr;
            }
            if (root->rightType == ChildType::Thread)
            {
                root->rightType = ChildType::Node;
                root->right = nullptr;
            }
        }
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::createInOrderThreadingTree(_TnBase *root)
        {
            _TnBase *_preNode = root;
            createInOrderThreadingTreePrivate(root, _preNode);
    
            if (_preNode->right == nullptr)
                _preNode->rightType = ChildType::Thread;
        }
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::createPreOrderThreadingTree(_TnBase *root)
        {
            _TnBase *_preNode = root;
            createPreOrderThreadingTreePrivate(root, _preNode);
    
            if (_preNode->right == nullptr)
                _preNode->rightType = ChildType::Thread;
        }
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::createSufixOrderThreadingTree(_TnBase *root)
        {
            _TnBase *_preNode = nullptr;
            createSufixOrderThreadingTreePrivate(root, _preNode);
    
            if (_preNode->right == nullptr)
                _preNode->rightType = ChildType::Thread;
        }
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::createInOrderThreadingTreePrivate(_TnBase *root, _TnBase *&_preNode)
        {
            if (root == nullptr)
                return;
            clearNodeType(root);
    
            if (root->leftType != ChildType::Thread)
                createInOrderThreadingTreePrivate(reinterpret_cast<_TnBase *>(root->left), _preNode);
            if (root->left == nullptr)
            {
                root->leftType = ChildType::Thread;
                root->left = _preNode;
            }
    
            if (_preNode->right == nullptr)
            {
                _preNode->rightType = ChildType::Thread;
                _preNode->right = root;
            }
            _preNode = root;
            if (root->rightType != ChildType::Thread)
                createInOrderThreadingTreePrivate(reinterpret_cast<_TnBase *>(root->right), _preNode);
        }
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::createPreOrderThreadingTreePrivate(_TnBase *root, _TnBase *&_preNode)
        {
            if (root == nullptr)
                return;
            clearNodeType(root);
    
            if (root->left == nullptr)
            {
                root->leftType = ChildType::Thread;
                root->left = _preNode;
            }
    
            if (_preNode->right == nullptr)
            {
                _preNode->rightType = ChildType::Thread;
                _preNode->right = root;
            }
    
            _preNode = root;
            if (root->leftType != ChildType::Thread)
                createPreOrderThreadingTreePrivate(reinterpret_cast<_TnBase *>(root->left), _preNode);
            
            if (root->rightType != ChildType::Thread)
                createPreOrderThreadingTreePrivate(reinterpret_cast<_TnBase *>(root->right), _preNode);
        }
    
        template<typename _TnBase>
        void TreeHelper<_TnBase>::createSufixOrderThreadingTreePrivate(_TnBase *root, _TnBase *&_preNode)
        {
            if (root == nullptr)
                return;
            clearNodeType(root);
    
            if (root->leftType != ChildType::Thread)
                createSufixOrderThreadingTreePrivate(reinterpret_cast<_TnBase *>(root->left), _preNode);
    
            if (root->rightType != ChildType::Thread)
                createSufixOrderThreadingTreePrivate(reinterpret_cast<_TnBase *>(root->right), _preNode);
    
            if (root->left == nullptr)
            {
                root->leftType = ChildType::Thread;
                root->left = _preNode;
            }
    
            if (_preNode != nullptr && _preNode->right == nullptr)
            {
                _preNode->rightType = ChildType::Thread;
                _preNode->right = root;
            }
    
            _preNode = root;
        }
    
        template<typename _TnBase>
        template<typename _Iter, typename _sizeType>
        inline _TnBase *TreeHelper<_TnBase>::preOrderInfixOrderToSufixOrder(_Iter &pre, _Iter &in, _sizeType length)
        {
            return preOrderInfixOrderToSufixOrderPirvate(pre, in, length, _TnBase::__isThreadingTree());
        }
    
        template<typename _TnBase>
        template<typename _Iter, typename _sizeType>
        inline static _TnBase *
            TreeHelper<_TnBase>::preOrderInfixOrderToSufixOrderPirvate(_Iter &pre, _Iter &in, _sizeType length, __trueType)
        {
            return preOrderInfixOrderToSufixOrderPirvate1(pre, in, length, __trueType());
        }
    
        template<typename _TnBase>
        template<typename _Iter, typename _sizeType>
        inline static _TnBase *
            TreeHelper<_TnBase>::preOrderInfixOrderToSufixOrderPirvate(_Iter &pre, _Iter &in, _sizeType length, __falseType)
        {
            return preOrderInfixOrderToSufixOrderPirvate1(pre, in, length, __falseType());
        }
    
        template<typename _TnBase>
        template<typename _Iter, typename _sizeType>
        _TnBase *TreeHelper<_TnBase>::preOrderInfixOrderToSufixOrderPirvate1(_Iter &pre, _Iter &in, _sizeType length, __trueType)
        {
            if (length == 0)
                return nullptr;
    
            auto node = new _TnBase;
            _sizeType index = 0;
    
            for (; index != length; index++)//找到对应的前序遍历的点
                if (*(in + index) == *(pre))
                    break;
    
            node->left = preOrderInfixOrderToSufixOrderPirvate1(pre + 1, in, index, __trueType());
            node->right = preOrderInfixOrderToSufixOrderPirvate1(pre + index + 1, in + index + 1, length - (index + 1), __trueType());
            node->val = *pre;
            _os << node->val << " ";
            return node;
        }
    
        template<typename _TnBase>
        template<typename _Iter, typename _sizeType>
        _TnBase *TreeHelper<_TnBase>::preOrderInfixOrderToSufixOrderPirvate1(_Iter &pre, _Iter &in, _sizeType length, __falseType)
        {
            if (length == 0)
                return nullptr;
    
            auto node = new _TnBase;
    
            _sizeType index = 0;
    
            for (; index != length; index++)//找到对应的前序遍历的点
                if (*(in + index) == *(pre))
                    break;
    
            node->left = preOrderInfixOrderToSufixOrderPirvate1(pre + 1, in, index, __falseType());
            node->right = preOrderInfixOrderToSufixOrderPirvate1(pre + index + 1, in + index + 1, length - (index + 1), __falseType());
            node->val = *pre;
            _os << node->val << " ";
            return node;
        }
  • 相关阅读:
    php投票系统
    php登陆和注册
    php常见报错
    session和cookie的区别
    php加密方法有哪些
    链接数据库封装类
    php数据库批量删除
    三傻大闹宝莱坞
    巴霍巴利王
    布拉德的中年危机
  • 原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/6619136.html
Copyright © 2011-2022 走看看