树的重建
任给一棵二叉树合法的两种遍历结果,就可以将它重建出来。事实上,不需重建这棵树,而进行隐式的遍历。可以尝试下面的这道题目:
对于编程之美3.9节的这个问题及其扩展问题,简单的实现代码如下:
对扩展问题1,显然是不唯一的,考虑所有节点都标注a的极端情况即知。实现方面,需要把下面的find查找修改为直到没有匹配为止,然后分别尝试重建。
template <class T>
struct Node {
T v;
Node *left, *right;
};
template<class It>
bool buildable(It preFirst, It preLast, It inFirst, It inLast) {
if (preFirst == preLast && inFirst == inLast) return true; // both empty
if (preFirst == preLast || inFirst == inLast) return false; // one empty
It inMid = find(inFirst, inLast, *preFirst);
if (inMid == inLast) return false;
It preMid = advance(preFirst, distance(inFirst, inMid) + 1);
if (!buildable(++preFirst, preMid, inFirst, inMid)) return false;
return buildable(preMid, preLast, ++inMid, inLast);
}
template <class It>
Node<typename iterator_traits<It>::value_type>*
buildTree(It preFirst, It preLast, It inFirst, It inLast) {
if (preFirst == preLast && inFirst == inLast) return;
// pre and in
It inMid = find(inFirst, inLast, *preFirst);
It preMid = advance(preFirst, distance(inFirst, inMid) + 1);
// pre and post
//It postMid = find(postFirst, --postLast, ++preFirst);
//It preMid = find(preFirst, preLast, *postLast);
// in and post
//It inMid = find(inFirst, inLast, *--postLast);
//It postMid = advance(postFirst, distance(inFirst, inMid) + 1);
typedef Node<typename iterator_traits<It>::value_type> NodeType;
NodeType* root = new NodeType;
root->v = *preFirst;
root->left = buildTree(++preFirst, preMid, inFirst, inMid);
root->right = buildTree(preMid, preLast, ++inMid, inLast);
return root;
}
template<class It>
Node<typename iterator_traits<It>::value_type>*
build(It preFirst, It preLast, It inFirst, It inLast) {
if (!buildable(preFirst, preLast, inFirst, inLast)) return 0;
return buildTree(preFirst, preLast, inFirst, inLast);
}