Binary subtree detection - Why to compare 2 traversals - algorithm

Why do we need to compare in-order traversal string AND pre-order traversal string to determine if a tree is a subtree of a bigger tree? Why is 1 traversal string not enough?
Can we replace one of the above strings with the post-order traversal string?
Assume:
I have an unbalanced binary tree. This is NOT necessarily a binary search tree.
Data at inner nodes and leaves can be compared using a given compareTO() method
The tree is huge, thus making use of suffix trees impossible. Assume normal recursion is possible.

Ad1. Let's say you have your bigger tree:
5
/
6 <something>
/ \
7 3
/
2
Now notice that the inorder traversal of the subtree rooted at node 6 will be [7,6,2,3]. Now tell me what will be the inorder traversal of the following tree:
6
/ \
7 2
\
3
You guessed it: [7,6,2,3]. Inorder traversal does not, in general case describe a single binary tree but a number of binary trees. Should this be a binary search tree then you only need 1 preorder or postorder traversal since the inorder traversal will always be the same (all nodes in a sorted order).
Ad2. You can reconstruct a tree with inorder and preorder or postorder traversals. You cannot, in the general case, reconstruct a tree with a preorder and postorder traversals, there might be more than 1 option. The only case where you can do that is for a full binary tree (each node, except the leaves, has to have 2 children).

Related

Find a binary tree given only in-order traversal

I'm given an in-order traversal and need to find a binary tree. I referred my sites and most of them said it is not possible. However, i think a non-unique binary tree is possible. Can i find a binary tree using just given in-order traversal? If not, can i find a corresponding pre-order traversal from the given in-order traversal?
I tried to convert the in-order into pre-order by selecting the central node of in-order as the root but I'm not sure if its correct. Please guide me.
Thank you.
Given just the in-order traversal of the nodes, and no more information in the question, you can find a binary tree, but as you said, there won't be a unique solution (especially if the tree doesn't have to be balanced). As a result, you can again find a pre-order traversal.
As an example, if your in-order traversal is [1,2,3,4,5,6,7,8], then even if the tree is balanced, there are multiple possibilities for the root node (namely, 4 or 5). If the tree doesn't have to be balanced, you could potentially pick any of these as the root node.
Here's an example of a non-balanced tree you could build after arbitrarily choosing 4 as the root node:
4
/ \
3 6
/ / \
2 5 7
/ \
1 8
Pre-order traversal for this tree would yield 4,3,2,1,6,5,7,8. Again, if the only requirements are that you just find a binary tree, this is just as valid as setting 1 as the root node and making everything else a right node:
1
\
2
\
3
\
4
\
5
\
6
\
7
\
8
The pre-order traversal for this tree would be 1,2,3,4,5,6,7,8. Since these trees both generate the same in-order traversal, but different pre-order traversals, there isn't guaranteed to be a single, unique tree or even a single, unique pre-order traversal for a given in-order traversal.
For more of one node there is no a unique binary search tree that contains the inorder traversal.
But if you want a tree, then just perform a random shuffle of inorder sequence and then insert the resulting randomized sequence in a binary search tree

Why it is impossible to construct Binary Tree with Pre-Order, Post Order and Level Order traversals given?

Given:
Pre-Order Traversal.
Post-Order Traversal.
Level-Order Traversal.
One can not contruct a Binary Tree with 12 or 23 or 31 or even if 123 are given! Why is this? and Why InOrder Traversal is very important to construct the original Tree?
We can't build a tree without the in-order traversal. Why? Let's say you are given the pre-order and post-order traversals only.A simple example is shown below.
Consider two different trees,
TREE 1:
root=a;
root->left=b;
root->left->right=c;
Tree 2:
root=a;
root->right=b;
root->right->left=c;
Both the trees are different, but have same pre-order and post-order sequence.
pre-order - a b c
post-order - c b a
This is so because we cannot separate the left sub-tree and right sub-tree using the pre-order or post-order traversal alone.
Pre-order, as its name, always visits root first and then left and right sub-trees. That is to say, walking through a pre-order list, each node we hit would be a "root" of a sub-tree.
Post-order, as its name, always visits left and right sub-trees first and then the root. That is to say, walking through a post-order list backward, each node we hit would be a "root" of a sub-tree.
In-order, on the other hand, always visits left sub-tree first and then root and then right sub-tree, which means that given a root(which we can obtain from the pre-order or post-order traversal as stated above), in-order traversal tells us the sizes of the left and right sub-trees of a given root and thus we can construct the original tree.(Think this out)
Same is the case with level-order traversal. Thus if we want to obtain a unique tree we need an in-order traversal along with any other of the three traversals.
Note - The exception is of course a full binary tree, in which pre-order and post-order traversals can be used to construct the tree, as there is no ambiguity in tree structure.

Preorder and Inorder of Trees with more than two children

We know that a given preorder and inorder traversal of a binary tree uniquely defines the tree , what about general trees i.e trees which have more than two children , does the preorder and inorder traversal have a one-one correspondence to the tree structure .
In other words given a tuple (preorder,inorder) of a general tree is it unique for a general tree or there can be many trees with the same tuple of preorder and inorder traversal ?
In-order traversal (visit the left subtree, visit the root, visit the right subtree) is not defined for a non-binary tree (there is no left and right subtree).
Obviously, pre-order does not define the tree uniquely. There is no difference between the path A, B, C and the tree with root A and children B and C.
However, the combination of pre-order and post-order uniquely defines your tree (provided that all nodes are unique). We can show this by induction. Clearly, the empty string uniquely defines an empty tree.
Now, given a non-empty pre-order and post-order string, it is obvious that the first node in the pre-order string (and the last in the post-order) is the root R of the tree. All we need to do now is identify the subtrees (and corresponding pre-order and post-order string) rooted at the children of R, because we can find their structure by the induction hypothesis.
Let RAaaaaaBbbbbb be the pre-order string and aaaaaAbbbbbBR the post-order string (a and b are arbitrary nodes). Clearly, A is the root of the first child of R, because it is the first successor in the pre-order string. In post-order, that subtree ends at A (by definition of post-order). We cut off that part and see that the second child of R must be B. There are no more children of R, because B is the last node in the post-order string. We now have two smaller subproblems: Aaaaaa, aaaaaA and Bbbbbb, bbbbbB. We can solve these by the induction hypothesis.
You can simply turn your general tree into a binary tree ( by taking a look at here ) and then traverse it.

Binary Search Tree pre-, in-, post-order traversal for given tree

I have Binary Search tree and have to perform three types of tree traversal:
Are this results correct?
Pre-order (root,left,right): 30,15,59,43,40,92
In-order (left,root,right): 15,30,59,40,43,92
Post-order (left,right,root): 15,59,40,43,92,30
UPDATE:
In-order: 15,30,40,43,59,92 (projection?)
Post-order: 15,40,43,92,59,30.
Is it right?
Given this updated tree, your preorder traversal is correct.
Your inorder traversal, though, is incorrect. As a hint, doing an inorder traversal of a binary tree always lists the values off in sorted order.
Finally, your postorder traversal is incorrect. The value 59 won't be produced until after all of the nodes in its two subtrees are produced, so it should come second-to-last. Using this fact, try seeing if you can come up with the correct answer.
Hope this helps!

checking subtrees using preorder and inorder strings

A book I'm reading claims that one way to check whether a binary tree B is a subtree of a binary tree A is to build the inorder and preorder strings (strings that represent the inorder and preorder traversal of each tree) of both trees, and check whether inorder_B is a substring of inorder_A and preorder_B is a substring of preorder_A. Note that it claims that you have to check substring match on both the inorder and preorder strings.
Is it really necessary to check for a substring match on both the inorder and preorder strings? Wouldn't it suffice to check either? Could someone provide an example to prove me wrong (i.e. prove the claim in the book right)? I couldn't come up with an example where two trees were unequal but the preorder or inorder strings match.
Consider the two two node trees with A and B as nodes. Tree one has B as root and A as left child. Tree two has A as root and B as right child. The inorder traversals match but the trees differ.
I think you need both if the tree is not a binary search tree but a plain binary tree. Any set of nodes can be a preorder notation. Suppose there is a binary tree a,b,c,d,e,f,g,h and your subtree is cdef. You can create another tree with subtree cde and another subtree fg. There is no way to know the difference.
If it is a binary search tree however you needn't have the inorder.
Incidentally here's an amusing algorithmic problem: given a preorder notation find the number of binary trees that satisfy it.
As supplement to user1952500's answer: if it is a binary search tree, either only preorder or only postorder can make it unique, while only inorder can not. For example:
5
/ \
3 6
inorder: 3-5-6
however, another binary search tree can have the same inorder:
3
\
5
\
6
Also, I believe preorder+inorder+string_comparison only works to check whether two trees are identical. It fails to check whether a tree is the subtree of another tree. To see an example, refer
Determine if a binary tree is subtree of another binary tree using pre-order and in-order strings
a preorder traversal with sentinel to represent null node is well enough.
we can use this approach to serialize/deserialize binary tree. it means there is one-to-one mapping between a binary tree and its preorder with sentinel representation.

Resources