遍历模板
其实这个问题想清楚了很简单,只要把这三个概念理解透彻就可以做出来了,比如前序遍历的第一个值一定是根节点,然后这个根节点对应到中序遍历里面,在中序遍历的这个值的两边的值,一定在以此节点为根节点的两个子树上,同理,后序遍历也一样。
已知前序遍历和后序遍历是不能求唯一的中序遍历树的。
#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; }