Assume you have two binary trees and you want to know whether one is a subtree of the other. One solution is to get the inorder and preorder traversals of both trees and check whether the traversals of the candidate subtree are substrings of the corresponding traversal for the other tree. I read several posts about this posts about this solution. One discussion shows that inorder AND preorder traversal are both necessary. Can someone explain why they are sufficient? Why is the case that if the inorder and preorder traversal of tree2 are substrings of those of tree1, then tree2 is a subtree of tree1?
2 Answers
People agreed that binary tree can represent the order on it's nodes by left/right relation. That means that left part comes before right part. You may call trees equivalent if the order is the same. So in-order string represents the the order and if you want to check the equivalence, then it is sufficient to check only in-order (by definition). But when you want to check the full equality of trees then we have to find the way how we can distinguish equivalent trees.For example it can be level-order check. But for subtrees level order doesn't fit, because the level order string for subtree is split. For pre-order you walk the subtree form root before other parts of tree.
Suppose equivalent trees are not equal, then traversing in pre-order everything will be equal until first differ. 2 situations can happen.
1) The value of node of one tree differs from another. That means that pre-order strings differs, because you walk the tree in pre-order.
2) Children signature (no children, only left, only right, both children) differs. But in this situation easy to understand that the in-order will change and trees are not equivalent, which contradicts the conditions.
Note that this works only when all the nodes are unique. If you have all nodes of value like "a" then no matter how you walk, your string is always "aa...a". So you have to distinguish the nodes somehow, not only by "value".
Q: One discussion shows that inorder AND preorder traversal are both necessary. Can someone explain why they are sufficient?
Because of the simple fact that it is possible to uniquely reconstruct a binary tree from these two traversals (or inorder and postorder, as well). Check this example:
Inorder : [1,2,3,4,5,6]
Preorder : [4,2,1,3,5,6]
From preorder, you know that 4 is the root of the tree. From inorder, you can determine the left and right subtree, and you proceed recursively from this point:
4
/ \
Left subtree Right subtree
Inorder : [1,2,3] Inorder : [5,6]
Preorder: [2,1,3] Preorder: [5,6]
Check for more details in this excellent article: Reconstructing binary trees from tree traversal. Since these two serializations (traversals actually serialize tree to a string) of the tree combined together have to be unique for a binary tree, we get that one tree is a subtree of another if and only if these traversals are substrings of other two serializations.