Application use case of Reverse Level Order Traversal - data-structures

Similar to how level order traversal in tree represents BFS in graph theory and thus has various applications such as finding shortest path between 2 nodes, what could be a use case of finding reverse of level order traversal.
For example:
Level Order Traversal of given tree is {1,2,3,4,5} i.e. level 0 to level n.
Reverse of Level Order Traversal for following tree would be {4,5,2,3,1} i.e. starting from level n to level 0.

Related

Depth First Search - Advantages of traversing random neighbours

Depth First Search allows to traverse adjacent vertices in an arbitrary order.
Are there any advantages in choosing random neighbours vs choosing neighbours in ascending fashion?
Consider the exploration order of following graph:
0 -> 9 -> 8 -> 7 ..
0 -> 1 -> 8 -> 7 ..
Can random choice lead to more favourable results?
Can I find a situation in which there is an advantage?
Yes. Easily. If I have a connected graph, traversing with random choices is guaranteed to eventually reach every node. Traversing in order is guaranteed to eventually wind up in a loop.
Is there an advantage in general?
No. For example in the connected example, a simple "keep track of where we have been" makes both reach everything. Which one will find a target node first will be a question of chance.
First of all, the DFS is not responsible for the arbitrary order.
The way of traversing the nodes depend on 2 things:
The order in which you pushed the adjacent nodes in the adjacency list (Generally influenced by the order of the edges provided in the input).
The custom order which you decide for traversal (as you mentioned, the sorted order).
Answer to your question:
Choosing the order in which you pushed the adjacent nodes in the adjacency list does not affect the complexity.
If you decide to traverse adjacent nodes in sorted, then you need to maintain the adjacency list accordingly, which comes at the cost of extra factor of V*log(V).
Overall time complexity = O(V+E) + O(V * log(V)).
O(V+E) => for DFS.
O(V * log(V)) => for priority queue/sorting the adjacency list.
Here, V = number of nodes in the graph and E = number of edges.

Partitioning a weighted tree to equally weighted subtrees

Input:
a rooted tree with n nodes;
each node p has positive integer weight w(p);
a node can have more than two children.
Problem:
divide the tree into k subtrees/partitions (obviously by removing k-1 edges);
subtree weight W(p) is the weight of all the nodes in a subtree rooted at node p;
all the subtrees should be weighted as evenly as possible - the difference between min(W(p)) and max(W(p)) should be as small as possible.
I've yet to find a suitable algorithm for this. Where should I start? Tips, instructions and pseudocode appreciated.
Assume you can't modify the tree other than to remove edges to create subtrees.
First understand that you cannot guarantee that by simply removing edges that you will have subtrees within an arbitrary bound. You can create tree that when you split them there is no way to create subtrees within a target bound. For example:
a(b(c,d,e,f),g)
You cannot split that into two balanced sections. The best you can do is remove the edge from a to b:
a(g) and b(c,d,e,f)
Also this criteria is a little underdefined when k > 2. What is better a split 10,10,10,1 or 10,10,6,5?
But you can come up with a method to split trees up in the most balanced way possible.
Implement you tree such that each node holds a count of all of its children. You can add this pretty efficiently to any tree. ( E.g. when you add a node you have to iterate up the chain of parent node incrementing the count. Remove a node and you iterate up subtracting from the count )
Then starting from the root iterate down, in a breadth first manner until you find a set of nodes that dominate child nodes in a way that is most balanced. I don't have an algorithm for this at the ready - but I think you can find one pretty readily.
I think something where when you want to divide into k subtrees you create an array of k tree roots. One of those nodes must always be the root of the current tree, then you iterate down looking for nodes to replace on of the k-1 candidates that improves the partitioning. You'll want some kind of terminating condition where you don't interate down to every leaf node. E.g. it never makes sense to subdivide anything by the largest candidate node.

What is the difference between breadth first searching and level order traversal?

I don't need code, just an explanation. My textbook says
level order: each node at level i is processed before any node at level i+1
My understanding of breadth first searching is that you explore nodes nearest the root first, starting from the left? How is this any different? Is this a square and rectangle sort of situation?
For a 'proper' tree (see below), it's the same thing, at least by most definitions. Like Wikipedia, for example:
Breadth-first
See also: Breadth-first search
Trees can also be traversed in level-order, ...
... a breadth-first (level-order) traversal ...
Well, at least level-order traversal is the same as breadth-first traversal. There are many reasons to traverse something, it doesn't just have to be to search, as breadth-first search seems to imply, although many (or most) don't make that distinction and use the terms interchangeably.
The only time I'd personally really use "level-order traversal" is when talking about in-, post- and pre-order traversals, just to follow the same "...-order traversal" format.
For a general graph, the concept of a 'level' may not be well-formed (although you could just define it as the (shortest) distance from the source node, I suppose), thus a level-order traversal may not be well-defined, but a breadth-first search still makes perfect sense.
I mentioned a 'proper' tree above (which is a totally made up sub-classification, in case you were wondering) - this simply means 'level' is defined as you'd expect - each edge increases the level by one. However, one may be able to play around with the definition of 'level' a bit (although doing this may not be widely accepted), in essence allowing edges to jump over levels (or even have edges between nodes on the same level). For example:
level
1 1
/ \
2 / 3
/ /
3 2 4
So the level-order traversal would be 1, 3, 2, 4,
while the breadth-first traversal would be 1, 2, 3, 4.
What is the difference between breadth first searching and level order traversal?
DEFINITION: "The level-order of an ordered tree is a listing of the vertices in the top-to-bottom, left-to-right order of a standard plane drawing of that tree".
Please bear in mind that when we are discussing level-order we are talking exclusively about Trees, and not graphs in general.
And we can be even more specific and say we are discussing about Rooted-Trees.
DEFINITION: "Rooted Tree is a tree with a designated vertex called the root. And each edge is considered to be directed away from the root. Thus, the rooted tree is a directed tree such that the root has indegree = 0 (so no incoming edges)".
*Its important to make the distinction because its this property that allows for the recursive implementation of trees.
Furthermore, level-order traversal would not make sense about a Graph (the tree is one specific type of a graph (no cycle and connected)).
So for graphs we use BFS and the BFS we use for trees has been termed "level-order traversal" (because since we are talking about rooted-trees, then levels do make sense. Whereas in a graph they would not make sense, due to the absence of the root).
Conclusion: Level-order traversal is the breadth-first-search for the case of the specific graph structure named: Tree (specifically Rooted-Trees)
we use level order traversal for trees because in trees there is no cycle and once a node is visited, it is not gonna visit again
but in graphs, its is not so.
Graph can be cyclic as well
and if a graph is cyclic, as per level order if a node is visited, it doesnt check it is visited or not and again it will traverse the same node infinite times. and program will continue to traverse because of cycle.
So we use BFS or DFS in case of graph.
In general, traversing is a technique of visiting all the elements only once in a data structure. The process of getting,modifying,checking the data of all nodes in a tree is called Tree Traversal.
Search means looking for an item. It does not mean that you are going to visit all nodes. Let's say you are looking for the first node whose value is less than 10, once you find 10, you exit searching.

No of trees can be constructed from given Inorder/Preorder/Postorder traversal

I know one cannot construct a tree without having both Inorder and Preorder/postorder traversals. Because for a given (only Inorder/Preorder/postorder) there could be a possibility of generating more number of trees. Are there any algorithms or mechanism one can compute the number of unique trees from a given (only Inorder/Preorder/postorder traversal).
Eg : a b c d e f g this is my Inorder traversal.
How many unique trees that can be constructed with the given Inorder traversal.
I tried them is google but none of the explanations are clear
Any help would be appreciated...
Well the algorithm is as follows:
Let, P(N) denote the number of trees possible with N nodes. Let the indexes of the nodes be 1,2,3,...
Now, lets pick the root of the tree. Any of the given N nodes can be the root. Say node i has been picked as root. Then, all the elements to the left of i in the inorder sequence must be in the left sub-tree. Similarly, to the right.
So, total possibilities are: P(i-1)*P(N-i)
In the above expression i varies from 1 to N.
Hence we have,
P(N) = P(0)*P(N-1) + P(1)*P(N-2) + P(2)*P(N-3)....
The base cases will be:
P(0) = 1
P(1) = 1
Thus this can be solved by using Dynamic Programming.
Note that a particular traversal is just a way of labeling the nodes in a tree, so that the number of possible binary trees is the same for any two traversals of the same length. The number of binary trees with n nodes is given by the n-1st Catalan number.
The formula
(2n)!/ (n)!(n+1)!
OR
2n * C(n) / (n+1)
gives the number of possible binary trees for any given INORDER/PREORDER/POSTORDER traversal.

tree traverse recursive in level-first order and depth-first order

Is there any algorithm can traverse a tree recursively in level-first order and non-recursively in postorder.Thanks a lot.
To get an effectively recursive breadth-first search you can use iterative deepening depth-first search. It's particularly good for situations where the branching factor is high, where regular breadth-first search tends to choke from excessive memory consumption.
Edit: Marcos Marin already mentioned it, but for the sake of completeness, the Wikipedia page on breadth-first traversal describes the algorithm thus:
Enqueue the root node.
Dequeue a node and examine it.
If the element sought is found in this node, quit the search and return a result.
Otherwise enqueue any successors (the direct child nodes) that have not yet been discovered.
If the queue is empty, every node on the graph has been examined – quit the search and return "not found".
Repeat from Step 2.
Note: Using a stack instead of a queue would turn this algorithm into a depth-first search.
That last line is, obviously, interesting to you if you want to do a non-recursive depth-first traversal. Getting pre- or post-order is just a matter of modifying how you append the nodes in step 2.b.
You can recurse a tree in post order iteratively by using a stack instead of the implicit call stack used in recursion.
Wikipedia says,
Traversal
Compared to linear data structures
like linked lists and one dimensional
arrays, which have only one logical
means of traversal, tree structures
can be traversed in many different
ways. Starting at the root of a binary
tree, there are three main steps that
can be performed and the order in
which they are performed defines the
traversal type.
These steps (in no
particular order) are: performing an
action on the current node (referred
to as "visiting" the node), traversing
to the left child node, and traversing
to the right child node. Thus the
process is most easily described
through recursion.
To traverse a non-empty binary tree in
preorder, perform the following
operations recursively at each node,
starting with the root node:
Visit the node.
Traverse the left subtree.
Traverse the right subtree. (This is also called Depth-first
traversal.)
To traverse a non-empty binary tree in
inorder, perform the following
operations recursively at each node:
Traverse the left subtree.
Visit the node.
Traverse the right subtree. (This is also called Symmetric traversal.)
To traverse a non-empty binary tree in
postorder, perform the following
operations recursively at each node:
Traverse the left subtree.
Traverse the right subtree.
Visit the node.
Finally, trees can also be traversed
in level-order, where we visit every
node on a level before going to a
lower level. This is also called
Breadth-first traversal.

Resources