views:

3802

answers:

4

Consider the situation where you have two lists of nodes of which all you know is that one is a representation of a preorder traversal of some tree and the other a representation of a postorder traversal of the same tree.

I believe it is possible to reconstruct the tree exactly from these two lists, and I think I have an algorithm to do it, but have not proven it. As this will be a part of a masters project I need to be absolutely certain that it is possible and correct (Mathematically proven). However it will not be the focus of the project, so I was wondering if there is a source out there (i.e. paper or book) I could quote for the proof. (Maybe in TAOCP? anybody know the section possibly?)

In short, I need a proven algorithm in a quotable resource that reconstructs a tree from its pre and post order traversals.


Note: The tree in question will probably not be binary, or balanced, or anything that would make it too easy.

Note2: Using only the preorder or the postorder list would be even better, but I do not think it is possible.

Note3: A node can have any amount of children.

Note4: I only care about the order of siblings. Left or right does not matter when there is only one child.

+4  A: 

Preorder and postorder do not uniquely define a tree. See the second example.

Bill the Lizard
Ah ... but I do not care about left or right children, only about the order of the siblings. I will edit my question. +1 for the source though.
NomeN
+1  A: 

You cannot use only one list, because you'll get no sense of the depth of the tree. Thus, you definitely require two or more lists.

Here's my attempt at a solution:

Use your preorder traversal as a means of knowing the ordering of the data. This makes sense because you know the first node is the top, and you know that data further to the left of the traversal belongs to the left of the tree, etc.

Your post order traversal can determine the depth of the tree. For example, let's say I have a structure like this:

      1
  2   5   6
 3 4  7

Where 2 is the parent of 3 and 4, and 5 is the parent of 7.

Preorder: 1 2 3 4 5 7 6
Postorder: 3 4 2 7 5 6 1

We know we start with 1, because it is the first node in the preorder traversal. Then we look at the next number, 2. In the post order, because the number 2 comes BEFORE node 1, we know that 2 has to be a child of 1. Next we look at 3. 3 comes before 2, and thus 3 is a child of 2. 4 is before 2 but after 3, so we know 4 is a child of 2 but NOT a child of 3. Etc.

Now, this may not work if the nodes are not unique, but at the very least its a start to a solution.

Edit: The order of the children is preserved with this solution, simply due to knowing the ordering of the nodes via the preorder traversal, and then knowing the structure via the postorder traversal.

Edit2: The proof may lie here: http://ieeexplore.ieee.org/Xplore/login.jsp?url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel2%2F215%2F626%2F00017225.pdf%3Farnumber%3D17225&authDecision=-203

I think you need to purchase the document, however...

Here is a written proof presented to be a solution:

http://www14.informatik.tu-muenchen.de/lehre/2007WS/fa-cse/tutorials/tutorial09-solutions.pdf

AlbertoPL
My solution is very similar, however I am looking for a proven algorithm. If there is none, I might try to prove my algorithm by SO. If even the whole SO community can not prove it wrong it must be right...right?
NomeN
If the whole SO community can not prove it wrong then it MIGHT be right :P
AlbertoPL
I say code this one, and try it with as many trees as you can, however I believe it to be mathematically sound, I'm just no good at starting off proofs from scratch.
AlbertoPL
Me neither, therefore the question...and it saves a hell of a lot of time even if I was proficient in writing proofs.
NomeN
I found a paper where two algorithms using pre and post order tree traversals reconstruct the tree. However, you have to pay for it...
AlbertoPL
Check the second source I just added as well, it's a written solution to the problem.
AlbertoPL
I am afraid both sources are about binary trees. I am not sure it can be generalized for trees with an arbitrary number of children.
NomeN
While it's not what you needed, here's a free version of the first article -- http://ntur.lib.ntu.edu.tw/bitstream/246246/2007041910032125/1/00017225.pdf
Richard Dunlap
Luckily, because this is a project for university at a research institution I have two ways of getting the article for free. Both have a subscription for all IEEE papers. But for anyone else viewing this... good job Alberto and Richard for finding free sources.
NomeN
A: 

Q.1 diffrerentiate between following a.preorder and postorder traversal in data structure b. breadth first traversal and depth first traversal in a graph of data structure.

komal
The question very clearly states pre and postorder traversal of a tree. (and next time, put this kind of question in a comment. Answers are for actual answers)
NomeN
+1  A: 

Consider an arbitrary tree T as the quadruple (A, B, C, D), where A is the root node, B is the root node of the first child, C is a vector of any non-empty children of B, and D is a vector of any non-empty siblings of B. The elements of C and D are themselves trees.

Any of A, B, C and D may be empty. If B is empty, so must be C and D; if A, then everything.

Since nodes are unique, the sets of nodes contained anywhere within C and D are disjoint, and neither contains A or B.

Functions pre() and post() generate ordered sequences of the form:

pre(T) = [A, B, pre(C), pre(D)]

post(T) = [post(C), B, post(D), A]

where the function applied to a vector is defined to be the concatenation of the sequences resulting from applying the function to each element in turn.

Now consider the cases:

  • if A is empty, the output of both functions is the empty sequence []
  • if B is empty, the output of both functions is just [A]
  • if C and D are empty, pre(T) = [A, B] and post(T) = [B, A]
  • if just C is empty, pre(T) = [A, B, D'] and post(T) = [B, D'', A] (where the primes indicate some permutation of the nodes contained within D)
  • if just D is empty, pre(T) = [A, B, C'] and post(T) = [C'', B, A]
  • if none are empty, pre(T) = [A, B, C', D'] and post(T) = [C'', B, D'', A]

In all cases we can unambiguously partition the members of the two output sequences into the appropriate subsequences, by using A and B (if present) as delimiters.

The question then is, can we also partition the vector sequences? If we can, then each can be recursively processed and we're done.

Since the result of pre() will always be a chain of sequences starting with A nodes, and the result of post() will always be a chain of sequences ending with A nodes, we can indeed divide them up, provided that the A nodes are never empty.

This is where the process falls down in the case of binary (or indeed any) trees with fixed children that may independently be empty. In our case, however, we have defined C and D to contain only non-empty nodes, and so the reconstruction is guaranteed to work.

Um, I think so, anyway. Obviously this is just an argument, not a formal proof!

walkytalky
I believe you came up with the exact same algorithm as I had in my mind, I eventually turned it into a little paper because I could not find any quotable resource. The principle idea being that you can recursively reconstruct the tree due to the position of the root of the (sub)tree in the pre and post respectively, all children will lie between those positions. The first child is then the leftmost of those nodes in pre, the second is the leftmost node that isnt a child of the first etc...
NomeN
And your efforts are very much appreciated, but I have to say... necromancy much? (+1 anyway)
NomeN
Just happened to be on the front page when I dropped in (thanks to komal's non-answer, I guess) and piqued my interest. How about posting a link to your paper for future reference?
walkytalky