struct Helper {
TreeNode* node;
int index;
public:
Helper(TreeNode* pNode, int idx)
: node(pNode), index(idx) { }
};当然。二叉树的节点也要有:
struct TreeNode {char data;TreeNode* lChild;TreeNode* rChild;
public:TreeNode(char c) : data(c), lChild(0), rChild(0) { }
}; 好了,我们一步一步来看看怎样解决这个还原二叉树的问题 (1) (A, 7) 取POST第一个字符。然后通过Helper放入list中,并构造出一个list的初始环境 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 POST: H I D J K E B M N F O P G C A MID: H D I B J E K A M F N C O G P 【list】 nod 0 A 0 idx -1 7 15 cur ^ nxt cur, nxt都是指向list中元素的指针。头尾两个元素表示边界 (2) (C, 11) 取POST第13个字符。依据list来判定它为谁的左孩子/右孩子 能够看到。pc=C,其在MID中的下标mi为11,简略为(C, 11),以后都这么简略 (C, 11)在(A, 7)右边,由于11 > 7,所以C为A的右孩子,并插入到list中,注意 cur指针的变动。 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 POST: H I D J K E B M N F O P G C A MID: H D I B J E K A M F N C O G P 【list】 nod 0 A C 0 idx -1 7 11 15 cur ^ nxt (3) (G, 13) (G, 13)在(C, 11)右边,由于 13 > 11。所以G是C的右孩子。插入list中 【list】 nod 0 A C G 0 idx -1 7 11 13 15 cur ^ nxt 以下省略。由于这个和我的另外一篇文章《前序-中序二叉树还原》非常像,仅仅只是一个从前往后 一个从后往前,另一个先确定左孩子,一个先确定右孩子罢了 以下讲一下当A的右子树都还原好了,如何还原B的情况。同一时候也解说了如何还原左孩子的方法。
(12)(B, 3) 这个时候链表应该是这种 【list】 nod 0 A M 0 idx -1 7 8 15 cur ^ nxt (B, 3)不在(M, 8)右边,nxt = cur, cur-- 【list】 nod 0 A M 0 idx -1 7 8 15 cur ^ nxt ^ (B, 3)不在(A, 7),(M, 8)中间。删除(M, 8) 【list】 nod 0 A 0 idx -1 7 15 cur ^ nxt (13)(B, 3) 此时(B, 3)不在(A, 7)右边。nxt = cur, cur-- 【list】 nod 0 A 0 idx -1 7 15 cur ^ nxt ^ (B, 3)在(0, -1),(A, 7)中间,因此B是A的左孩子,删除A,插入B,cur指向B 【list】 nod 0 B 0 idx -1 3 15 cur ^ nxt
对了,千万不要忘记在确定X节点是Y节点的左/右孩子后要做对应的链接操作。
以下给出算法的C++表示。这里我们用iterator来表示cur, nxt指针。
我们之所以要用list是 由于list在插入/删除元素后iterator不会失效。另一点,由于list<>::iterator不支持 random access。所以我们要用nxt, cur两个iterator表示一前一后,否则的话直接用cur和 cur - 1即可了,这种话就简单多了。 【源代码实现】