画圆的沙滩

亦简亦美

树的重建

任给一棵二叉树合法的两种遍历结果,就可以将它重建出来。事实上,不需重建这棵树,而进行隐式的遍历。可以尝试下面的这道题目:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=104&page=show_problem&problem=489

对于编程之美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);
}

posted on 2011-03-21 18:07  acmaru  阅读(174)  评论(0编辑  收藏  举报

导航