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