when to use inorder, preorder and postorder traversal - binary-search-tree

I understand the code behind how to do inorder, preorder, and postorder traversal on a binary search tree. However, I'm confused about the application.
When would you use each? It would be really helpful to illustrate cases of when each method of traversal makes the most sense.
Thanks!

Inorder traversal simply processes the items in the defined order. If, for example, you have a BST of a list of words or names, inorder traversal would print them out in order.
Preorder and postorder traversal most often apply to trees other than binary search trees. For example, to evaluate an expression like A + B * C, you can create a tree like this:
To evaluate the expression, you traverse the tree in postorder, applying each operator to the values from each of its sub-trees.
Preorder traversal could be used for roughly the same purpose if you wanted (for example) to produce output in a language something like Lisp, so the expression should come out as (add A (mul B C)).

Related

Why is this binary search tree an example of pre-order?

I'm a bit confused. I'm trying to learn about binary search tree's at the moment, and my understanding is that, in pre-order traversing, the left branch node value should be less than the root value. E.g., root: 7, leftchild: 6, rightchild: 8.
But I've seen this example of pre-order traversal that goes: 1 2 4 5 3. And images re-iterate that 1 is the root, and 2 is the leftchild node. But 2 is obviously more than 1.
Am I misunderstanding something?
Your understanding of binary search trees is correct.
But pre-order traversals (and other types of traversals) are not just a thing for binary search trees. You will find examples of such traversals of other types of trees that are not necessarily binary search trees. Preorder, postorder, breadth-first and depth-first traversals are also relevant for any other kind of tree -- they don't have to be search trees, and not even binary.
Only inorder traversals assume the tree is binary. And if that inorder traversal happens to visit the tree values in their proper order, then we are dealing with a binary search tree.

Can a binary search tree be skewed?

What I am trying to ask is whether a binary search tree is self-blancing or if it can also become skewed?
I tried looking for an unbalanced binary search tree and could not really find anything.
So is a BST different from a self-balancing BST?
is a BST different from a self-balancing BST?
Self-balancing binary search trees are binary search trees which have logic added to them for keeping the tree more or less balanced.
So every self-balancing BST is a BST, but not every BST is self-balancing.
In fact, with a binary search tree we can refer to a data structure without any algorithm that goes with it. For instance:
4
/ \
2 8
\
3
This represents a binary search tree. Nothing more needs to be said about how you would insert or delete a node. It might even be immutable, not allowing any insertions or deletions. It still is a binary search tree.
Can a binary search tree be skewed?
Yes. The following is a valid binary search tree, although not one that will allow for efficient look-ups:
5
/
4
/
3
/
2
/
1
A self-balancing binary search tree, is one that has specific algorithms associated with it for insertion and deletion that will include rebalancing logic.
There are many different self-balancing binary search trees:
AVL tree
Red-black tree
Variants:
AA tree
B-tree
Variants:
B+ tree
Splay tree
Treap
Scapegoat tree
Tango tree

Inorder successor of a binary tree (NOT BST)

Can someone help me to figure out how to find inorder successor of a binary tree for a given node(not a binary search tree)? I know how to find it in a binary search tree: It will be the left-most leaf of the right subtree. However, I am not sure how it is done if the tree is not a BST.
I don't think I can go to the right child and then to the leftmost leaf node. (OR is there a difference between finding inorder successor in a BST and normal BT)?
Thank you.
Is there a difference between finding inorder successor in a BST and normal BT?
No, there isn't. An inorder ordering is one that applies to binary trees in general.
The only difference in effect, is that an inorder traversal on a BST will produce a sequence of values that is ordered by value. But that is just a nice property that applies to a BST. It does not affect the meaning of what inorder represents.

Cypher BFS with multiple Relations in Path

I'd like to model autonomous systems and their relationships in Graph Database (memgraph-db)
There are two different kinds of relationships that can exist between nodes:
undirected peer2peer relationships (edges without arrows in image)
directed provider2customer relationships (arrows pointing to provider in image)
The following image shows valid paths that I want to find with some query
They can be described as
(s)-[:provider*0..n]->()-[:peer*0..n]—()<-[:provider*0..n]-(d)
or in other words
0-n c2p edges followed by 0-n p2p edges followed by 0-n p2c edges
I can fix the first and last node and would like to find a (shortest/cheapest) path. As I understand I can do BFS if there is ONE relation on the path.
Is there a way to query for paths of such form in Cypher?
As an alternative I could do individual queries where I specify the length of each of the segments and then do a query for every length of path until a path is found.
i.e.
MATCH (s)<-[]->(d) // All one hop paths
MATCH (s)-[:provider]->()-[:peer]-(d)
MATCH (s)-[:provider]->()<-[:provider]-(d)
...
Since it's viable to have 7 different path sections, I don't see how 3 BFS patterns (... BFS*0..n) would yield a valid solution. It's impossible to have an empty path because the pattern contains some nodes between them (I have to double-check that).
Writing individual patterns is not great.
Some options are:
MATCH path=(s)-[:BFS*0.n]-(d) WHERE {{filter_expression}} -> The expression has to be quite complex in order to yield valid paths.
MATCH path=(s)-[:BFS*0.n]-(d) CALL module.filter_procedure(path) -> The module.procedure(path) could be implemented in Python or C/C++. Please take a look here. I would recommend starting with Python since it's much easier. Python for the PoC should be fine. I would also recommend starting with this option because I'm pretty confident the solution will work, + it's modular. After all, the filter_procedure could be extended easily, while the query will stay the same.
Could you please provide a sample dataset in a format of a Cypher query (a couple of nodes and edges / a small graph)? I'm glad to come up with a solution.

Which is faster, a ternary search tree or a binary search tree?

ternery search tree requires O(log(n)+k) comparisons where n is number of strings and k is the length of the string to be searched and binary search tree requires log(n) comparisons then why is TST faster than BST ?
Because in the ternary case it is log3(n) where in the binary case it is log2(n).
Ternary search trees are specifically designed to store strings, so our analysis is going to need to take into account that each item stored is a string with some length. Let's say that the length of the longest string in the data structure is L and that there are n total strings.
You're correct that a binary search tree makes only O(log n) comparisons when doing a lookup. However, since the items stored in the tree are all strings, each one of those comparisons takes time O(L) to complete. Consequently, the actual runtime of doing a search with a binary search tree in this case would be O(L log n), since there are O(log n) comparisons costing O(L) time each.
Now, let's consider a ternary search tree. With a standard TST implementation, for each character of the input string to look up, we do a BST lookup to find the tree to descend into. This takes time O(log n) and we do it L times for a total runtime of O(L log n), matching the BST lookup time. However, you can actually improve upon this by replacing the standard BSTs in the ternary search tree with weight-balanced trees whose weight is given by the number of strings in each subtree, a more careful analysis can be used to show that the total runtime for a lookup will be O(L + log n), which is significantly faster than a standard BST lookup.
Hope this helps!