I am currently considering different ways to accomplish the task of converting a family-type general tree (where each parent can have as many children as necessary) to a binary tree such that the left child of the parent node is inserted to the left of the parent and the right child of the parent node is inserted to the right of the (oldest) child node and so on.
This is the structure of how the binary tree must look like when converted from the general tree: https://www.geeksforgeeks.org/convert-a-generic-treen-array-tree-to-binary-tree/
I fed in my data by creating class object GTNode for the General Tree to add the nodes with the following values being passed:
//name = value1; numChildren = value2
GTNode gtn = new GTNode (String name, int numChildren);
No issues with constructor, this is purely to illustrated the main focus of the node is indeed the name of the family member. Thus this really can't be converted and sorted by a Binary Search Tree and is not the point of the resulting program I'm trying to create.
I was able to create methods to traverse the tree just fine, but it really doesn't help in the conversion process to the CONVERTED binary tree.
Therefore I created an additional section of code to create a linked list of the data. The reason why I did this was to establish pointers along the list which would point to the correct parent to add children to. Siblings would then be added to the right of the oldest sibling based on pointers based on where we were along real-time adding of nodes in the tree. By this time you can imagine I have two pointers going in my linked list traversal and three pointers along the tree nodes.
I can't seem to make good progress on an algorithm to create this binary tree from the data. here's a little sample code mostly pseudo code to show you basically how I'm adding nodes to the converted-style binary tree based on general tree data.
p=q=first; //initialize to first node f the linked list of family data
//ex. [Tom, 2] [Marc,1] [Ron,0] [Billy, 0] where Marc and Ron are Tom's children, and Billy is Marc's child)
z=root;
//I already established x, y = root earlier and moved pointer .next in order to add children nodes to the siblings
//here we establish x and y pointers for the tree and add our root node and first child node, which will always be to the left.
//I left it out of the while loop, because I was running into problems with null pointers.
{
while (p.next!=null && q.next!=null)
{
for (i = n; i>0; i--) //int n = node.numChildren; was declared earlier and then decreased
// n-=1 to accommodate the first child being added to left of parent node;
{
//add nodes left or right to parent node: still trying to figure out the appropriate condition
//statements to determine addLeft or addRight from node
}
//here we change the pointer of the GENERAL tree parent node based on the linked list
// add new to binary tree to the right of the last child i.e.
y = new BTNode(p.value,p.numChildren);
y = x.right;
x = y.parent;
x = y; //move pointer along
q = q.next; //q moves from Tom to Marc.
n = q.numChildren;
//go to beginning of while loop and as you can see, if n>0 it iterates based on the number of children
// if n=0 exits loop and creates a new node to the right
}
}
I'm wondering if this is an acceptable track to go down in terms of operability. Optimization I'm not as focused on because this is a difficult task... but could be taken into account.
Looking for pseudocode or java code shippers that would help in establishing an algorithm along these lines, or error in my logic. Again, not looking for an argument against doing a conversion like this because I want to see what it would look like as is.
Thanks!
Related
I am working on a school project and I need to build a Data Structure that has a root node, multiple "ending" nodes(the end of the data Structure), and undefined number of nodes(that have at most two directed links to other nodes) in between the root node and the multiple "ending" nodes. I was thinking of creating some sort of binary graph (represented as a adjacency matrix) where each node can lead to a max of two other nodes, but I don't know how I would construct it in such a way that there is a root node and ending nodes. Can anyone give ideas on how I would do this or a better way to do it? Thank you.(It needs to be in java)
Also, I forgot to mention that I would be adding elements to the data structure and that all paths down the structure would eventually have to lead to one of the preset ending nodes.
Why the adjacency matrix? You're right about the binary tree (or DAG, to be precise). A node can be represented with this class:
class BinaryTree<T> {
BinaryTree<T> left;
BinaryTree<T> right;
}
Ending nodes would be the nodes with left == null && right == null.
I'm doing this assignment right now and one of the methods I need to write is getting a node reference given a certain String label.
One of the fields in my node contains a String called label and I want to check my entire tree to see if a particular node contains that specific String.
How would I go about doing this?
So far I have a method called getNodeReference that takes a String label and I want to do something like:
if(root != contain the String) {
--search the left children, middle children, then right children (I guess its a ternary tree)
}
if (left.node != contain the String) {
--keep searching left, if you cant find it go on to middle. etc.
}
The kind of operation you are referring to are called Tree Traversals. A good reference on how to perform them is:
https://en.wikipedia.org/wiki/Tree_traversal
But an example could be (in pseudocode):
Set up a queue.
Enqueue the root.
While the queue is not empty:
Dequeue an item.
If the item matches, return it.
Else
Iterate over the children of the item, enqueuing them
in order from left to right.
This is referred to as a Breadth First Search. It is up to you to figure out how to do a similar Depth First Search, but I'll give you a hint. A stack might be involved.
This is kind of a confusing question so I apologize as I'm not quite sure how to phrase it. Basically what I'm doing is working with sorting binary search trees. Throughout the program, the user adds a record to the tree, which is a node containing (int studentNumber, String firstName, String lastName, String major, double gpa). At the end of the program, the nodes are transposed to a LinkedList with a custom Node class I made, and then that list is serialized into a file.
Now, on start up, I want to basically read that file back into another list, display the list, then add it back into the BST so it can be sorted in various ways. My question stands on the point of reading each line (node) in the file and pulling the fields (int studentNumber, String firstName, String lastName, String major, double gpa) back into the tree from each "node". This is what I have so far in my read section:
public void loadRecord(LinkedList list) {
File file = new File("records.txt");
try
{
LinkedList<Node> list2;
ObjectInputStream input = new ObjectInputStream(new FileInputStream(file));
list2 = (LinkedList<Node>)input.readObject();
if (list2.size() > 0){
list.addAll(list2);
}//end if
else {
System.out.println("No elements");
}
}
//Catch Exceptions
//display list
}//end loadRecord
Once again.. I apologize if this makes no sense at all. And it's very possible I'm going in the completely wrong direction, so I appreciate any feedback. Please let me know what you think!
First, a
linked list and a binary search tree are two different data structures. You can't make one with another.
Let's say you have a list of numbers you want to store. The data is added to both structures in the same order. The linked list will look something like:
|5|-->|3|-->|7|-->|2|-->|6|-->|4|-->|8|-->|1|
"|x|" represents a node with x the data stored in it.
The arrow represents the reference a node has to its next.
data is ordered the same way it is entered.
The binary search tree:
5
/ \
/ \
3 7
/ \ / \
2 4 6 8
/
1
For each parent node there is a reference for a left node and a right node. The data in the left child node is smaller than the data in parent node and the data on the right child node is larger on that of the parent.
Therefore, whatever data is being entered it must be 'comparable' in a sense that one value can be larger or smaller than another. So if your data stored is students then one student must be of larger value than another(higher gpa, larger student number, last alphabetically in name, etc.).
Unlike a linked list, the standard API doesn't provide a binary search tree class.So you have implement your own. You need to be familiar with recursion to implement the BST. Make sure you decide how students are compared and implement the tree accordingly. Here is a link that can help :Binary Search Tree and Tree Traversal .
Next, you need to extract the student info from the record file and store it in the tree. It would help if you stated how the student information is ordered in the record.txt file.For now, I will assume that it is ordered such that data of each student is written in one line. I would implement a method in custom node(should called student) class that takes in a line,parses it, and store the data in the student's fields.
Then I would make a while loop that creates a new student, adds the current line to the appropriate method of the student object, and adds the student object into the tree as long as there is a next line in the input stream.
As I said, I will need more information on record file to explain further. Let me know if you need anymore clarifications.
I have to write an algorithm for my project. Following is the problem
A Tree like Structure for which only one functionality is exposed i.e to **getAllChildNodes** which returns all the children of a particular node.
Now I am given an array of Nodes , I have to only retain the topmost parent node among them.
Example : Lets say there are 3 trees
Tree 1 : P1 has two children C11 & C12
Tree 2 : P2 has 1 children C21, and C21 has 2 child C22, C23
Tree 3 : P3 has 2 Children C31 and C32
Now if given an array say { C11, C21, C22 , P1, P3, C32}
The expected result is { C21, P1 , P3 }
Let me know if more information is required from my side.
More info :
I have done it by first getting all the child of first element of array and then compare with rest of the elements of array ,and similarly with each element. but this has more complexity.. i.e n*n*getAllChildNodes. I am here for a better suggestion
Pick ith element of array and add all its children to a hashmap(using the given function). Do this for i 1 to n(complete pass)
Loop i for 1 to n and for each iteration, check if the element is present in hashmap.
If it is present, delete it from the array,
else continue
Note the order of checking if element belong to hashmap is O(1) and also order of addition is O(1), avearage. So the algorithm is O(n*getAllChlidNodes) average
You can do this easily.
first create a method isPresent(node) to check if the node you are entering is present in the array. Then enter each node given to find its parent.
if(isPresent(x->parent)) push(x->parent);
Continue this for the entire list.
Now recursively check to see if the current list has any parents present. Once you start doing you'll get it. If there are any parents just pop() those elements.
Hope this helps :)
If you could get a function first like getParentNode(childNode) or create map/multimap of child as key and parent as value as pre processing step then Problem would become very easy.
If you have getParentNode(childNode) then just walk through the array and push the parents into set.
If you have map/multimap of child as key and parent as value as pre processing step then apply the algo as mentioned by adi
I have the following directed graph implementation
Nodes nod[]
List<Arcs> arc[]
So the node on the n'th position has all his arcs of the list in position n. Of course, the nodes are organized accordingly, so that I can use Binary Search.
Based on this implementation. I wish to create a DFS algorithm. I know very well the pseudo code, adapting to java shouldn't be a problem.
But my question is the following. In DFS we need to start searching from the "top" node. And thinking about it, i dont have this "top" node. Moreover, I have no idea how to get it.
So I ask, how do i get this top node, considering my implementation?
Thanks for the help.
Expanding on my comment:
Assuming that the arcs are directed (i.e., from the parent node to the child only) you can search all of the nodes for the one with no incoming arcs:
// parent_count is an integer array of the same size as nod[]
for i = 1..n
for each arc in arc[i] (arc going from i to j)
increment parent_count[j]
end
end
for k = 1..n
if parent_count[k] == 0
return k
end
DFS/BFS are very common and general algorithms to travel over the graph, both has no special meaning of top node, you could start DFS from any node. For example, DFS is used in topological sort algorithm and it states that we have to start from nodes with no incoming edges.
Could you please highlight what problem you want to solve? This should help us to find nodes that has to be used as a roots for DFS.