For the structure given in below data model, where each node is,
type Person {
firstName,
lastName,
Pointer to list of his children,
Pointer to next node
}
This data model neither looks like tree nor graph.
what is the name of this data model?
This is a tree in the left-child right-sibling representation.
A multi-child tree basically needs a dynamic data structure within each node to represent the children. Sometimes, fixed-size nodes are preferred for various reasons. This representation allows doing so in a fixed amount of space per node - the first child only is recorded, and all the children form a linked list. Obviously, searching the children of a node in this representation, is linear in the number of children.
Looks like a Directed acyclic graph to me.
https://en.wikipedia.org/wiki/Directed_acyclic_graph
Related
I working on a simple water pipeline path modelling and listing each path.
The model is simple because the pipes do not create loops or grids. It consists of nodes which are representing the edge of each pipe segment.
Based on this we can say it is similar to a Binary Tree data model. However, as I understand, trees are hierarchical data structures. And also, I see on https://www.geeksforgeeks.org/print-root-leaf-path-without-using-recursion/?ref=lbp that, data is defined with left-right-left.left etc, by describing the exact location of each node.
In my case, the data should include only the start and end nodes for each pipe segment. Each node should also include info if it is the source (root) or leaf node. Number of leaf nodes will be equal to number of paths.
My model does not require any hierarchy and also it does not require left-right definition.
In this case we may say it is similar to a Graph, but my model also does not have loops or grids.
So please advise how to model this and create an algorithm.
Assume we have a DAG with a single leaf Node leafN. Each node is an object containing list of parent nodes. Node class can be something like class Node(Object, List[Node].
How to construct a DAG from leafN?
For e.g., given leaf node leafD with two parents, leafD(Object#123, List(leafC(leafA(null)), leafB(leafA(null)))) it's DAG will be:
leafA
/ \
leafB leafC
\ /
leafD
i.e., leafA(leafB(leafD(null)), leafC(leafD(null))) (I am ignoring the objects from every node for clarity.)
In short we have a leaf node with parent pointers which themselves have parent pointers and finally, after applying an algorithm, we want a root node with pointers to children nodes which further have pointers to children nodes.
Code ain't required, algorithm or links to any will suffice.
This is pretty simple, once you realise that notionally only the direction of the edges in the DAG has changed.
Instead of the Parent ---> Child node relationship, you have a Child ---> Parent relationship.
As such, all you need to do is construct a DAG from the given relationships, assuming that the Child node is actually the parent, and the parent nodes are childs.
So you end up with
leafD
↙ ↘
leafB leafC
↘ ↙
leafA
Now, all you need to do is reverse the edges in the DAG.
This is pretty simple, One way to do it would be to walk through the DAG, and get all the edge relationships, and then reverse them one by one.
Another would be to do this recursively using level order traversal.
Check this question for more solutions around how to reverse a DAG.
All you need to do is to put your nodes into some data structure that allows you to find a node easily. If your integer values in your node are sequential (or close to it) and start at a low number then you can use an array and just put the node with integer i in position i of the array (This makes including the integer in the node somewhat redundant).
This is all explained well on this site (but note that in their implementation the list is of the edges to, not the edges from) http://algs4.cs.princeton.edu/42directed/
We all know what a tree is: on the first level of a tree we have a root, and from the root come branches that are trees as well. But how do I name the "opposite" structure: on the i-th level we have a set of "leaf" nodes, and those nodes form groups of 1+ nodes, and a group points to a "trunk" node on i+1th level. If you want a visual example, imagine raindrops flowing down a window and combining as they collide.
A lot of tree data structures are actually constructed from leaf to root, and can be stored to allow for going one or both directions.
I don't think it really has a special name as it's more a convention than a requirement for trees typically to go from root to leaf rather than the other way or both ways. Also there are a number of tree data structures that allow for going both ways.
Every tree is a DAG, a directed acyclic graph, and so is the data-structure that you describe. What you describe is also a multitree, a subset of DAGs. Possibly there is a more precise real subset of multitrees that describes your graph, but I am not aware of it. Hope this helps.
How to find a loop in a binary tree? I am looking for a solution other than marking the visited nodes as visited or doing a address hashing. Any ideas?
Suppose you have a binary tree but you don't trust it and you think it might be a graph, the general case will dictate to remember the visited nodes. It is, somewhat, the same algorithm to construct a minimum spanning tree from a graph and this means the space and time complexity will be an issue.
Another approach would be to consider the data you save in the tree. Consider you have numbers of hashes so you can compare.
A pseudocode would test for this conditions:
Every node would have to have a maximum of 2 children and 1 parent (max 3 connections). More then 3 connections => not a binary tree.
The parent must not be a child.
If a node has two children, then the left child has a smaller value than the parent and the right child has a bigger value. So considering this, if a leaf, or inner node has as a child some node on a higher level (like parent's parent) you can determine a loop based on the values. If a child is a right node then it's value must be bigger then it's parent but if that child forms a loop, it means he is from the left part or the right part of the parent.
3.a. So if it is from the left part then it's value is smaller than it's sibling. So => not a binary tree. The idea is somewhat the same for the other part.
Testing aside, in what form is the tree that you want to test? Remeber that every node has a pointer to it's parent. An this pointer points to a single parent. So depending of the format you tree is in, you can take advantage from this.
As mentioned already: A tree does not (by definition) contain cycles (loops).
To test if your directed graph contains cycles (references to nodes already added to the tree) you can iterate trough the tree and add each node to a visited-list (or the hash of it if you rather prefer) and check each new node if it is in the list.
Plenty of algorithms for cycle-detection in graphs are just a google-search away.
I have a data such that there are many parents each with 0-n children where each child can have 0-n nodes. Each node has a unique identifier (key) Ultimately, the parents are not connected to each other. It seems like this would be a list of trees, however that seems imprecise. I was thinking of joining them with a dummy root.
I need to be able to assembly a list of nodes that occur:
from any given node down (children)
from any given node down (children) then up to the root (up to the specific parent)
the top level parent of any given node (in an O(n) operation)
the level of the child in the tree (in an O(n) operation)
The structure will contain 300,000 nodes.
I was thinking perhaps I could implement a List of Trees and then also maintain a hash lookup structure that will reference a specific key value to provide me with a node as a starting point.
Is this a logical structure? Is there a better way to handle it? It seems crude to me.
If you are concerned in find a root node quickly you can think of create a tree where each node points to another tree.