Breadth First Search and Depth First Search - algorithm

Can anybody give a link for a simple explanation on BFS and DFS with its implementation?

Depth First Search:

Lets say you are given the following structure:
Format: Node [Children]
A [B C D]
B [E F]
C [G]
D []
E []
F []
G []
A breadth first search visits all of a node's children before visiting their children. Here's the pseudocode and the solution for the above structure:
1. Enqueue root node.
2. Dequeue and output. If the queue is empty, go to step 5.
3. Enqueue the dequeued node's children.
4. Go to Step 2.
5. Done
Two queues: (Active Node) [Output] [Working Set]
Starting with root:
( ) [] [A]
(A) [A] [B C D]
(B) [A B] [C D E F]
(C) [A B C] [D E F G]
(D) [A B C D] [E F G]
(E) [A B C D E] [F G]
(F) [A B C D E F] [G]
(G) [A B C D E F G] []
Done
A depth first search visits the lowest level (deepest children) of the tree first instead. There are two types of depth first search: pre-order and post-order. This just differentiates between when you add the node to the output (when you visit it vs leave it).
var rootNode = structure.getRoot();
var preOrder = new Array();
var postOrder = new Array();
function DepthFirst( rootNode ){
// Pre-order
preOrder[ preOrder.length ] = rootNode;
for( var child in rootNode ){
DepthFirst( child );
}
// Post-order
postOrder[ postOrder.length ] = rootNode;
}
Pre-order:
* A B E F C G D
Post-order:
* E F B G C D A

Say you have a tree as follows:
It may be a little confusing because E is both a child of A and F but it helps illustrate the depth in a depth first search. A depth first search searches the tree going as deep (hence the term depth) as it can first. So the traversal left to right would be A, B, D, F, E, C, G.
A breadth first search evaluates all the children first before proceeding to the children of the children. So the same tree would go A, B, C, E, D, F, G.
Hope this helps.

you can find everything on wiki:
BFS and DFS
this link can be useful too. if you want an implementation go to: c++ boost library: DFS

Here are a few links to check out:
Breadth-first search
BFS is an uninformed search method that aims to expand and examine all nodes of a graph or combination of sequences by systematically searching through every solution. In other words, it exhaustively searches the entire graph or sequence without considering the goal until it finds it.
Depth-first search
Formally, DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found, or until it hits a node that has no children. Then the search backtracks, returning to the most recent node it hasn't finished exploring
Not only do they contain good explanations on how they are implemented in applications but also some algorithm pseudo code.

Breadth First Search/Depth First Search Animations

graph traversal with dfs and bfs.
in c++ and python.

Heres the idea in basics:
get a new queue ...initalize it with the root node .... loop through the entire queue and keep removing an item from the queue and printing it out (or saving it etc) and check if the same item has any children , if so push them onto the queue and continue in the loop until you traverse the entire segment(graph)...

snippet with 2 pointers.
void BFS(int v,struct Node **p)
{
struct Node *u;
visited[v-1] = TRUE;
printf("%d\t",v);
AddQueue(v);
while(IsEmpty() == FALSE)
{
v = DeleteQueue();
u = *(p+v-1);
while(u!=NULL)
{
if(visited(u->data -1) == FALSE)
{
AddQueue(u->data);
visited[u->data -1]=TRUE;
printf("%d\t",u->data);
}
u = u->next;
}
}
}

BFS and DFS are applicable to all kinds of graphs. I explain it for binary tree only. BFS visit each node top to bottom, left to right. For example for this:
1
/ \
7 9
\ / \
8 2 3
BFS gives us: 1 7 9 8 2 3. DFS visits depth of each branch first. Then, it comes back to its parents. You can follow this informal rule. First left child then right child then parent. But, you need to start from the depth of each branch. For example, here you start from 8, since there is no left child for 7. Then, you visit parent 7. Then, 1 parent of 7 will be visited. Then, you go to right branch. But, this time there is 2 as the left most child. So, you visit 2 (left child) then, right child 3 then, 9 their parents. So, DFS gives us 8 7 1 2 9 3. This is the implementation:
import java.util.ArrayList;
import java.util.List;
public class TreeTraverse {
static class Node{
Node(int data){
this.data = data;
this.left = null;
this.right = null;
this.visited = false;
}
int data;
Node left;
Node right;
boolean visited;
}
public static void main(String[] args) {
//The tree:
// 1
// / \
// 7 9
// \ / \
// 8 2 3
Node node1 = new Node(1);
Node node7 = new Node(7);
Node node9 = new Node(9);
Node node8 = new Node(8);
Node node2 = new Node(2);
Node node3 = new Node(3);
node1.left = node7;
node1.right = node9;
node7.right = node8;
node9.right = node3;
node9.left = node2;
System.out.println("DFS: ");
depthFirstSearch(node1);
System.out.println("\nBFS: ");
breadthFirstSearch(node1);
}
private static void depthFirstSearch(Node node){
if(node.left == null && node.right == null){
System.out.print(node.data+" ");
node.visited = true;
}else if(node.left == null || node.left.visited){
depthFirstSearch(node.right);
System.out.print(node.data+" ");
node.visited = true;
}else{
depthFirstSearch(node.left);
node.visited = true;
System.out.print(node.data+" ");
depthFirstSearch(node.right);
}
}
private static void breadthFirstSearch(Node node){
List<Node> al = new ArrayList<>();
al.add(node);
while(!al.isEmpty()){
node = al.get(0);
if(node.left != null){
int index = al.size();
al.add(index,node.left);
}
if(node.right != null){
int index = al.size();
al.add(index,node.right);
}
System.out.print(al.get(0).data+" ");
al.remove(0);
}
}
}
I hope it helps. If you want to clone the project, please visit: https://github.com/m-vahidalizadeh/foundations/blob/master/src/algorithms/TreeTraverse.java. I hope it helps.

First of all, BFS and DFS are two ways to implement binary tree traversal. Breadth First means level order traversal. Depth First has three ways to implemnt -- , , .
Preorder:
a. Start with root,
b. mark it visited,
c. go to left node
d. (b) - mark it visited
e. Repeat (c) till there is not any new left node remaining
(We are/might be at leaf node at this point,)
f. Is there any right node available? If yes, go to (a).
Level Order Traversal
Time Complexity
O(n)- Number of times each node is visited is 1 only, means total is n times.
Space Complexity-
Best Case: Tree only left nodes, is O(1)
Average Case: Perfect binary tree is example, n/2 number of nodes, O(n)

Related

How to find the leaf-only parent nodes in an n-ary tree

I'm trying to solve the following algorithm:
You have an n-ary tree. Find all the nodes satisfying the following
condition:
the node has child node(s) but all of the child nodes are leafs (they have no children ). Return a list of leaf only parent nodes and
their depth in the tree.
So if I have the tree below, the only node satisfying the above condition is D, because it has descendants (E) but they don't have children.
I am root!
/\ \
A B F
/\
C D
\
E
I'm trying to implement this in Java but pseudocode will also work for me.
I have the tree and node structures implemented here: N-ary trees in Java.
All I need is the algorithm.
start at root
while left son exists : go to left son
go back to father and check next son
if has no other sons : insert father to list
else insert father to list and go to step 2 but keep a depth counter and if found grandchildren : remove father from list
if finished all nodes : return list
root
/ \ \
A B F
/ \
C D
\
E
run example:
go to A
go back to root and insert root to list
go to B
go to C (remove root from potential because of counter)
go back to B and add B to list
go to D
go to E (remove B from potential because of counter)
go back to D and insert to list
go back to B
go back to root
go to F (don't insert root because root was already inserted [and removed]
return list which has only D
To make this work you should have a counter running for the node you are checking (to see if grandchildren exist) and also you should have a way of knowing if a node has been removed from the list so you would not insert it again (I didn't explicitly write it but I used 2 list - 1 for potentials and 1 for final)
OK, I got it. Here's the solution I've reached. I'm sure there are better solutions though - you're welcome to correct me.
// kick off the recursion
public Map<Integer, Integer> findLeafOnlyParents(GenericTree<Integer> tree){
Map<Integer, Integer> resultMap = new HashMap<>();
// start search from the root
traverseWithDepth(tree.getRoot(), resultMap, 0);
return resultMap;
}
private void traverseWithDepth(GenericTreeNode<Integer> node, Map<Integer, Integer> traversalResult, int depth) {
// check if the current note in the traversal is parent Of leaf-only nodes
if (isParentOfLeafOnly(node)){
traversalResult.put(node.data, depth);
}
// check the node's children
for(GenericTreeNode<Integer> child : node.getChildren()) {
traverseWithDepth(child, traversalResult, depth + 1);
}
}
// the main logic is here
private boolean isParentOfLeafOnly(GenericTreeNode<Integer> node){
boolean isParentOfLeafOnly = false;
// check if the node has children
if(node.getChildren().size() > 0){
// check the children of the node - they should not have children
List<GenericTreeNode<Integer>> children = node.getChildren();
boolean grandChildrenExist = false;
// for each child check if it has children of its own
for(GenericTreeNode<Integer> child : children) {
grandChildrenExist = child.getChildren().size() > 0;
// once found note that the current node has grandchildren,
// so we don't need to check the rest of the children of the node
if (grandChildrenExist){
break;
}
}
// we need only the parents who don't have great children
isParentOfLeafOnly = !grandChildrenExist;
}
return isParentOfLeafOnly;
}

sort graph by distance to end nodes

I have a list of nodes which belong in a graph. The graph is directed and does not contain cycles. Also, some of the nodes are marked as "end" nodes. Every node has a set of input nodes I can use.
The question is the following: How can I sort (ascending) the nodes in the list by the biggest distance to any reachable end node? Here is an example off how the graph could look like.
I have already added the calculated distance after which I can sort the nodes (grey). The end nodes have the distance 0 while C, D and G have the distance 1. However, F has the distance of 3 because the approach over D would be shorter (2).
I have made a concept of which I think, the problem would be solved. Here is some pseudo-code:
sortedTable<Node, depth> // used to store nodes and their currently calculated distance
tempTable<Node>// used to store nodes
currentDepth = 0;
- fill tempTable with end nodes
while( tempTable is not empty)
{
- create empty newTempTable<Node node>
// add tempTable to sortedTable
for (every "node" in tempTable)
{
if("node" is in sortedTable)
{
- overwrite depth in sortedTable with currentDepth
}
else
{
- add (node, currentDepth) to sortedTable
}
// get the node in the next layer
for ( every "newNode" connected to node)
{
- add newNode to newTempTable
}
- tempTable = newTempTable
}
currentDepth++;
}
This approach should work. However, the problem with this algorithm is that it basicly creates a tree from the graph based from every end node and then corrects old distance-calculations for every depth. For example: G would have the depth 1 (calculatet directly over B), then the depth 3 (calculated over A, D and F) and then depth 4 (calculated over A, C, E and F).
Do you have a better solution to this problem?
It can be done with dynamic programming.
The graph is a DAG, so first do a topological sort on the graph, let the sorted order be v1,v2,v3,...,vn.
Now, set D(v)=0 for all "end node", and from last to first (according to topological order) do:
D(v) = max { D(u) + 1, for each edge (v,u) }
It works because the graph is a DAG, and when done in reversed to the topological order, the values of all D(u) for all outgoing edges (v,u) is already known.
Example on your graph:
Topological sort (one possible):
H,G,B,F,D,E,C,A
Then, the algorithm:
init:
D(B)=D(A)=0
Go back from last to first:
D(A) - no out edges, done
D(C) = max{D(A) + 1} = max{0+1}=1
D(E) = max{D(C) + 1} = 2
D(D) = max{D(A) + 1} = 1
D(F) = max{D(E)+1, D(D)+1} = max{2+1,1+1} = 3
D(B) = 0
D(G) = max{D(B)+1,D(F)+1} = max{1,4}=4
D(H) = max{D(G) + 1} = 5
As a side note, if the graph is not a DAG, but a general graph, this is a variant of the Longest Path Problem, which is NP-Complete.
Luckily, it does have an efficient solution when our graph is a DAG.

Edge classification during Breadth-first search on a directed graph

I am having difficulties finding a way to properly classify the edges while a breadth-first search on a directed graph.
During a breadth-first or depth-first search, you can classify the edges met with 4 classes:
TREE
BACK
CROSS
FORWARD
Skiena [1] gives an implementation. If you move along an edge from v1 to v2, here is a way to return the class during a DFS in java, for reference. The parents map returns the parent vertex for the current search, and the timeOf() method, the time at which the vertex has been discovered.
if ( v1.equals( parents.get( v2 ) ) ) { return EdgeClass.TREE; }
if ( discovered.contains( v2 ) && !processed.contains( v2 ) ) { return EdgeClass.BACK; }
if ( processed.contains( v2 ) )
{
if ( timeOf( v1 ) < timeOf( v2 ) )
{
return EdgeClass.FORWARD;
}
else
{
return EdgeClass.CROSS;
}
}
return EdgeClass.UNCLASSIFIED;
My problem is that I cannot get it right for a Breadth first search on a directed graph. For instance:
The following graph - that is a loop - is ok:
A -> B
A -> C
B -> C
BFSing from A, B will be discovered, then C. The edges eAB and eAC are TREE edges, and when eBC is crossed last, B and C are processed and discovered, and this edge is properly classified as CROSS.
But a plain loop does not work:
A -> B
B -> C
C -> A
When the edge eCA is crossed last, A is processed and discovered. So this edge is incorrectly labeled as CROSS, whether it should be a BACK edge.
There is indeed no difference in the way the two cases are treated, even if the two edges have different classes.
How do you implement a proper edge classification for a BFS on a directed graph?
[1] http://www.algorist.com/
EDIT
Here an implementation derived from #redtuna answer.
I just added a check not to fetch the parent of the root.
I have JUnits tests that show it works for directed and undirected graphs, in the case of a loop, a straight line, a fork, a standard example, a single edge, etc....
#Override
public EdgeClass edgeClass( final V from, final V to )
{
if ( !discovered.contains( to ) ) { return EdgeClass.TREE; }
int toDepth = depths.get( to );
int fromDepth = depths.get( from );
V b = to;
while ( toDepth > 0 && fromDepth < toDepth )
{
b = parents.get( b );
toDepth = depths.get( b );
}
V a = from;
while ( fromDepth > 0 && toDepth < fromDepth )
{
a = parents.get( a );
fromDepth = depths.get( a );
}
if ( a.equals( b ) )
{
return EdgeClass.BACK;
}
else
{
return EdgeClass.CROSS;
}
}
How do you implement a proper edge classification for a BFS on a
directed graph?
As you already established, seeing a node for the first time creates a tree edge. The problem with BFS instead of DFS, as David Eisenstat said before me, is that back edges cannot be distinguished from cross ones just based on traversal order.
Instead, you need to do a bit of extra work to distinguish them. The key, as you'll see, is to use the definition of a cross edge.
The simplest (but memory-intensive) way is to associate every node with the set of its predecessors. This can be done trivially when you visit nodes. When finding a non-tree edge between nodes a and b, consider their predecessor sets. If one is a proper subset of the other, then you have a back edge. Otherwise, it's a cross edge. This comes directly from the definition of a cross edge: it's an edge between nodes where neither is the ancestor nor the descendant of the other on the tree.
A better way is to associate only a "depth" number with each node instead of a set. Again, this is readily done as you visit nodes. Now when you find a non-tree edge between a and b, start from the deeper of the two nodes and follow the tree edges backwards until you go back to the same depth as the other. So for example suppose a was deeper. Then you repeatedly compute a=parent(a) until depth(a)=depth(b).
If at this point a=b then you can classify the edge as a back edge because, as per the definition, one of the nodes is an ancestor of the other on the tree. Otherwise you can classify it as a cross edge because we know that neither node is an ancestor or descendant of the other.
pseudocode:
foreach edge(a,b) in BFS order:
if !b.known then:
b.known = true
b.depth = a.depth+1
edge type is TREE
continue to next edge
while (b.depth > a.depth): b=parent(b)
while (a.depth > b.depth): a=parent(a)
if a==b then:
edge type is BACK
else:
edge type is CROSS
The key property of DFS here is that, given two nodes u and v, the interval [u.discovered, u.processed] is a subinterval of [v.discovered, v.processed] if and only if u is a descendant of v. The times in BFS do not have this property; you have to do something else, e.g., compute the intervals via DFS on the tree that BFS produced. Then the classification pseudocode is 1. check for membership in the tree (tree edge) 2. check for head's interval contains tail's (back edge) 3. check for tail's interval contains head's (forward edge) 4. otherwise, declare a cross edge.
Instead of timeof(), you need an other vertex property, which contains the distance from the root. Let name that distance.
You have to processing a v vertex in the following way:
for (v0 in v.neighbours) {
if (!v0.discovered) {
v0.discovered = true;
v0.parent = v;
v0.distance = v.distance + 1;
}
}
v.processed = true;
After you processed a vertex a v vertex, you can run the following algorithm for every edge (from v1 to v2) of the v:
if (!v1.discovered) return EdgeClass.BACK;
else if (!v2.discovered) return EdgeClass.FORWARD;
else if (v1.distance == v2.distance) return EdgeClass.CROSS;
else if (v1.distance > v2.distance) return EdgeClass.BACK;
else {
if (v2.parent == v1) return EdgeClass.TREE;
else return EdgeClass.FORWARD;
}

Algorithm to find lowest common ancestor in directed acyclic graph?

Imagine a directed acyclic graph as follows, where:
"A" is the root (there is always exactly one root)
each node knows its parent(s)
the node names are arbitrary - nothing can be inferred from them
we know from another source that the nodes were added to the tree in the order A to G (e.g. they are commits in a version control system)
What algorithm could I use to determine the lowest common ancestor (LCA) of two arbitrary nodes, for example, the common ancestor of:
B and E is B
D and F is B
Note:
There is not necessarily a single path to a given node from the root (e.g. "G" has two paths), so you can't simply traverse paths from root to the two nodes and look for the last equal element
I've found LCA algorithms for trees, especially binary trees, but they do not apply here because a node can have multiple parents (i.e. this is not a tree)
Den Roman's link (Archived version) seems promising, but it seemed a little bit complicated to me, so I tried another approach. Here is a simple algorithm I used:
Let say you want to compute LCA(x,y) with x and y two nodes.
Each node must have a value color and count, resp. initialized to white and 0.
Color all ancestors of x as blue (can be done using BFS)
Color all blue ancestors of y as red (BFS again)
For each red node in the graph, increment its parents' count by one
Each red node having a count value set to 0 is a solution.
There can be more than one solution, depending on your graph. For instance, consider this graph:
LCA(4,5) possible solutions are 1 and 2.
Note it still work if you want find the LCA of 3 nodes or more, you just need to add a different color for each of them.
I was looking for a solution to the same problem and I found a solution in the following paper:
http://dx.doi.org/10.1016/j.ipl.2010.02.014
In short, you are not looking for the lowest common ancestor, but for the lowest SINGLE common ancestor, which they define in this paper.
I know it's and old question and pretty good discussion, but since I had some similar problem to solve I came across JGraphT's Lowest Common Ancestor algorithms, thought this might be of help:
NativeLcaFinder
TarjanLowestCommonAncestor
Just some wild thinking. What about using both input nodes as roots, and doing two BFS simultaneously step by step. At a certain step, when there are overlapping in their BLACK sets (recording visited nodes), algorithm stops and the overlapped nodes are their LCA(s). In this way, any other common ancestors will have longer distances than what we have discovered.
Assume that you want to find the ancestors of x and y in a graph.
Maintain an array of vectors- parents (storing parents of each node).
Firstly do a bfs(keep storing parents of each vertex) and find all the ancestors of x (find parents of x and using parents, find all the ancestors of x) and store them in a vector. Also, store the depth of each parent in the vector.
Find the ancestors of y using same method and store them in another vector. Now, you have two vectors storing the ancestors of x and y respectively along with their depth.
LCA would be common ancestor with greatest depth. Depth is defined as longest distance from root(vertex with in_degree=0). Now, we can sort the vectors in decreasing order of their depths and find out the LCA. Using this method, we can even find multiple LCA's (if there).
This link (Archived version) describes how it is done in Mercurial - the basic idea is to find all parents for the specified nodes, group them per distance from the root, then do a search on those groups.
If the graph has cycles then 'ancestor' is loosely defined. Perhaps you mean the ancestor on the tree output of a DFS or BFS? Or perhaps by 'ancestor' you mean the node in the digraph that minimizes the number of hops from E and B?
If you're not worried about complexity, then you could compute an A* (or Dijkstra's shortest path) from every node to both E and B. For the nodes that can reach both E and B, you can find the node that minimizes PathLengthToE + PathLengthToB.
EDIT:
Now that you've clarified a few things, I think I understand what you're looking for.
If you can only go "up" the tree, then I suggest you perform a BFS from E and also a BFS from B. Every node in your graph will have two variables associated with it: hops from B and hops from E. Let both B and E have copies of the list of graph nodes. B's list is sorted by hops from B while E's list is sorted by hops from E.
For each element in B's list, attempt to find it in E's list. Place matches in a third list, sorted by hops from B + hops from E. After you've exhausted B's list, your third sorted list should contain the LCA at its head. This allows for one solution, multiple solutions(arbitrarily chosen among by their BFS ordering for B), or no solution.
I also need exactly same thing , to find LCA in a DAG (directed acyclic graph). LCA problem is related to RMQ (Range Minimum Query Problem).
It is possible to reduce LCA to RMQ and find desired LCA of two arbitrary node from a directed acyclic graph.
I found THIS TUTORIAL detail and good. I am also planing to implement this.
I am proposing O(|V| + |E|) time complexity solution, and i think this approach is correct otherwise please correct me.
Given directed acyclic graph, we need to find LCA of two vertices v and w.
Step1: Find shortest distance of all vertices from root vertex using bfs http://en.wikipedia.org/wiki/Breadth-first_search with time complexity O(|V| + |E|) and also find the parent of each vertices.
Step2: Find the common ancestors of both the vertices by using parent until we reach root vertex Time complexity- 2|v|
Step3: LCA will be that common ancestor which have maximum shortest distance.
So, this is O(|V| + |E|) time complexity algorithm.
Please, correct me if i am wrong or any other suggestions are welcome.
package FB;
import java.util.*;
public class commomAnsectorForGraph {
public static void main(String[] args){
commomAnsectorForGraph com = new commomAnsectorForGraph();
graphNode g = new graphNode('g');
graphNode d = new graphNode('d');
graphNode f = new graphNode('f');
graphNode c = new graphNode('c');
graphNode e = new graphNode('e');
graphNode a = new graphNode('a');
graphNode b = new graphNode('b');
List<graphNode> gc = new ArrayList<>();
gc.add(d);
gc.add(f);
g.children = gc;
List<graphNode> dc = new ArrayList<>();
dc.add(c);
d.children = dc;
List<graphNode> cc = new ArrayList<>();
cc.add(b);
c.children = cc;
List<graphNode> bc = new ArrayList<>();
bc.add(a);
b.children = bc;
List<graphNode> fc = new ArrayList<>();
fc.add(e);
f.children = fc;
List<graphNode> ec = new ArrayList<>();
ec.add(b);
e.children = ec;
List<graphNode> ac = new ArrayList<>();
a.children = ac;
graphNode gn = com.findAncestor(g, c, d);
System.out.println(gn.value);
}
public graphNode findAncestor(graphNode root, graphNode a, graphNode b){
if(root == null) return null;
if(root.value == a.value || root.value == b.value) return root;
List<graphNode> list = root.children;
int count = 0;
List<graphNode> temp = new ArrayList<>();
for(graphNode node : list){
graphNode res = findAncestor(node, a, b);
temp.add(res);
if(res != null) {
count++;
}
}
if(count == 2) return root;
for(graphNode t : temp){
if(t != null) return t;
}
return null;
}
}
class graphNode{
char value;
graphNode parent;
List<graphNode> children;
public graphNode(char value){
this.value = value;
}
}
Everyone.
Try please in Java.
static String recentCommonAncestor(String[] commitHashes, String[][] ancestors, String strID, String strID1)
{
HashSet<String> setOfAncestorsLower = new HashSet<String>();
HashSet<String> setOfAncestorsUpper = new HashSet<String>();
String[] arrPair= {strID, strID1};
Arrays.sort(arrPair);
Comparator<String> comp = new Comparator<String>(){
#Override
public int compare(String s1, String s2) {
return s2.compareTo(s1);
}};
int indexUpper = Arrays.binarySearch(commitHashes, arrPair[0], comp);
int indexLower = Arrays.binarySearch(commitHashes, arrPair[1], comp);
setOfAncestorsLower.addAll(Arrays.asList(ancestors[indexLower]));
setOfAncestorsUpper.addAll(Arrays.asList(ancestors[indexUpper]));
HashSet<String>[] sets = new HashSet[] {setOfAncestorsLower, setOfAncestorsUpper};
for (int i = indexLower + 1; i < commitHashes.length; i++)
{
for (int j = 0; j < 2; j++)
{
if (sets[j].contains(commitHashes[i]))
{
if (i > indexUpper)
if(sets[1 - j].contains(commitHashes[i]))
return commitHashes[i];
sets[j].addAll(Arrays.asList(ancestors[i]));
}
}
}
return null;
}
The idea is very simple. We suppose that commitHashes ordered in downgrade sequence.
We find lowest and upper indexes of strings(hashes-does not mean).
It is clearly that (considering descendant order) the common ancestor can be only after upper index (lower value among hashes).
Then we start enumerating the hashes of commit and build chain of descendent parent chains . For this purpose we have two hashsets are initialised by parents of lowest and upper hash of commit. setOfAncestorsLower, setOfAncestorsUpper. If next hash -commit belongs to any of chains(hashsets),
then if current index is upper than index of lowest hash, then if it is contained in another set (chain) we return the current hash as result. If not, we add its parents (ancestors[i]) to hashset, which traces set of ancestors of set,, where the current element contained. That is the all, basically

Inorder tree traversal: Which definition is correct?

I have the following text from an academic course I took a while ago about inorder traversal (they also call it pancaking) of a binary tree (not BST):
Inorder tree traversal
Draw a line around the outside of the
tree. Start to the left of the root,
and go around the outside of the tree,
to end up to the right of the root.
Stay as close to the tree as possible,
but do not cross the tree. (Think of
the tree — its branches and nodes — as
a solid barrier.) The order of the
nodes is the order in which this line
passes underneath them. If you are
unsure as to when you go “underneath”
a node, remember that a node “to the
left” always comes first.
Here's the example used (slightly different tree from below)
However when I do a search on google, I get a conflicting definition. For example the wikipedia example:
Inorder traversal sequence: A, B, C,
D, E, F, G, H, I
(leftchild,rootnode,right node)
But according to (my understanding of) definition #1, this should be
A, B, D, C, E, F, G, I, H
Can anyone clarify which definition is correct? They might be both describing different traversal methods, but happen to be using the same name. I'm having trouble believing the peer-reviewed academic text is wrong, but can't be certain.
In my bad attempt at the drawing here's the order that shows how they should be picked.
pretty much pick the node that is directly above the line being drawn,.
Forget the definitions, it's so much easier to just apply the algorithm:
void inOrderPrint(Node root)
{
if (root.left != null) inOrderPrint(root.left);
print(root.name);
if (root.right != null) inOrderPrint(root.right);
}
It's just three lines. Rearrange the order for pre- and post- order.
If you read carefully you see that the first "definition" says to start left of the root and that the order of the nodes is determined by when you pass under them. So B is not the first node, as you pass it from the left on the way to A, then first pass under A after which you go up and pass under B. Therefore it seems that both definitions give the same result.
I personally found this lecture quite helpful.
Both definitions give the same result. Don't be fooled by the letters in the first example - look at the numbers along the path. The second example does use letters to denote the path - perhaps that is what is throwing you off.
For example, in your example order showing how you thought the second tree would be traversed using the algorithm of the first one, you place "D" after "B" but you shouldn't because there is still a left-hand child node of D available (that's why the first item says "the order in which this line passes underneath them."
this may be late but it could be useful for anyone later ..
u just need not to ignore the dummy or null nodes e.g the Node G has a left null node .. considering this null node will make every thing alright ..
The proper traversal would be: as far left as possible with leaf nodes (not root nodes)
Left Root Right
A B NULL
C D E
Null F G
H I NULL
F is root or left, i am not sure
I think the first binary tree with the root of a is a Binary tree which is not correctly constructed.
Try to implement so that all the left side of the tree is less than the root and all the right side of the tree is greater than or equal to the root.
But according to (my understanding of)
definition #1, this should be
A, B, D, C, E, F, G, I, H
Unfortunately, your understanding is wrong.
Whenever you arrive at a node, you must descend to an available left node, before you look at the current node, then you look at an available right node.
When you chose D before C, you didn't descend to the left node first.
Hey according to me as mentioned in wiki is correct the sequence for a inorder traversal is left-root-right.
Till A, B, C, D, E, F i think you have understood already. Now after root F the next node is G that doesn't hav a left node but a right node so as per the rule (left-root-right) its null-g-right. Now I is the right node of G but I has a left node hence the traversal would be GHI. This is correct.
Hope this helps.
For an inline tree traversal you have to keep in mind that the order of traversal is left-node-right. For the above diagram that you are conflicted on, your error occurs when you read a parent node before reading any leaf(children) nodes to the left.
The proper traversal would be: as far left as possible with leaf nodes(A), return to parent node(B), move to the right, but since D has a child to its left you move down again(C), back up to C's parent(D), to D's right child(E), reverse back to the root(F), move to the right leaf(G), move to G's leaf but since it has a left leaf node move there(H), return to parent(I).
the above traversal reads the node when I have it listed in parenthesis.
package datastructure;
public class BinaryTreeTraversal {
public static Node<Integer> node;
public static Node<Integer> sortedArrayToBST(int arr[], int start, int end) {
if (start > end)
return null;
int mid = start + (end - start) / 2;
Node<Integer> node = new Node<Integer>();
node.setValue(arr[mid]);
node.left = sortedArrayToBST(arr, start, mid - 1);
node.right = sortedArrayToBST(arr, mid + 1, end);
return node;
}
public static void main(String[] args) {
int[] test = new int[] { 1, 2, 3, 4, 5, 6, 7 };
Node<Integer> node = sortedArrayToBST(test, 0, test.length - 1);
System.out.println("preOrderTraversal >> ");
preOrderTraversal(node);
System.out.println("");
System.out.println("inOrderTraversal >> ");
inOrderTraversal(node);
System.out.println("");
System.out.println("postOrderTraversal >> ");
postOrderTraversal(node);
}
public static void preOrderTraversal(Node<Integer> node) {
if (node != null) {
System.out.print(" " + node.toString());
preOrderTraversal(node.left);
preOrderTraversal(node.right);
}
}
public static void inOrderTraversal(Node<Integer> node) {
if (node != null) {
inOrderTraversal(node.left);
System.out.print(" " + node.toString());
inOrderTraversal(node.right);
}
}
public static void postOrderTraversal(Node<Integer> node) {
if (node != null) {
postOrderTraversal(node.left);
postOrderTraversal(node.right);
System.out.print(" " + node.toString());
}
}
}
package datastructure;
public class Node {
E value = null;
Node<E> left;
Node<E> right;
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
public Node<E> getLeft() {
return left;
}
public void setLeft(Node<E> left) {
this.left = left;
}
public Node<E> getRight() {
return right;
}
public void setRight(Node<E> right) {
this.right = right;
}
#Override
public String toString() {
return " " +value;
}
}
preOrderTraversal >>
4 2 1 3 6 5 7
inOrderTraversal >>
1 2 3 4 5 6 7
postOrderTraversal >>
1 3 2 5 7 6 4
void
inorder (NODE root)
{
if (root != NULL)
{
inorder (root->llink);
printf ("%d\t", root->info);
inorder (root->rlink);
}
}
This the most simplest approach to recursive definition of in-order traversal, just call this function in the main function to get the in-order traversal of a given binary tree.
It is correct for preorder,nt for inorder

Resources