I'm trying to create binary tree that contains two int values and one string value sorted in the lexicographic, but I'm not sure what to do. I've created an array list, which has been already sorted, but the binary tree has to be a reference-based which is not sorted and I'm thinking about sorting the list while creating it. Can any one help with this? Any brief idea would be appreciated.
Binary tree is a recursive thing. Make a class called BinaryTree (i hope you are in C++, or .NET or JAVA) that has two references to two other BinaryTrees (null by default). Then make an insert function that is recursive.
I don't know what you are trying to accomplish, but when building a binary tree, arrays are usually nowhere to be found.
You first should create a class to store your data and implement Comparable or use a Comparator.
public class Data { // Implement Comparable...
private String s;
private int n1;
private int n2;
// Implement constructors, getters, setters based on what you need...
// Implement compareTo (+ equals + hashCode) unless your going with Comparator
}
Then use a Collection that implements SortedSet to store your data, TreeSet is a good choice. The objects in the SortedSet are stored by reference so if you modify a value set in a local variable it will be modified in the collection as well.
Edit: If I understood your question about reference based lists correctly the following is possible in Java.
List<Data> dataList = // Create list and add data into it.
Data data = dataList.get(4);
data.setS(103); // Modifies S in the local data-object and in dataList because they are reference based.
It sounds like you already have a data structure to store your two int values and a string (since you have them sorted in an array list). You can include this data structure in a "tree node". A node typically has a reference pointer to a parent node (unless it is the root node) and 2 child nodes.
Since you want the tree to be sorted what you're really after is a special form of binary tree called a heap. The link to the Binary Heap wikipedia page below has an algorithm to show how to sort a binary heap.
http://en.wikipedia.org/wiki/Binary_heap
Here's some more general information on heaps and trees.
http://en.wikipedia.org/wiki/Binary_tree
http://en.wikipedia.org/wiki/Heap_(data_structure)
EDIT: You don't have to use a literal tree structure to store the your data in a tree form. It is perfectly acceptable to build a tree using an array. Instead of using reference pointers (parent and 1 or 2 child nodes) you can compute an index into the array. Each set of children is considered a "row" in the tree. The root element is on the zero row. It's two children are on the first row. The children of the root's children are on the second row, and so on.
Using this pattern the children of any node can be found using array[2*n+1] and array[2*n+2] where n is the row of the parent node. The parent of any node can be found by using array[floor( (n-1)/2)].
Related
I'm studying Cracking the Coding Interview, and the code for constructing a Node class has a int data variable. What is the point of this variable? What does it refer to in the list?
The field
int data
is an example of what you hold inside a node, an element that you actually care for in the list.
Let's say you want to keep a list of integers in given order. The data field is your integer (for example profit of your company in some preconfigured order), while the Node object encapsulates it and also holds a reference to the next object (in single linked list)
This may be a too-specific question, but I'm hoping there's a more general solution to my problem.
I have a class. In this class is a tree-type structure with many parent/child nodes. Also in this class is an Array filled with references to each node in this tree-type structure.
The tree's purpose is for each node to know where to draw itself on screen (every node has relative positional information based on its parent's location).
The Array's purpose is the draw order, I simply draw whatever node is referenced at Array[0] first and so on. (So, the nodes aren't being drawn in the order they appear in the tree necessarily).
My problem is this. I want to clone this overall class that contains these two objects (tree with nodes and an Array that references said nodes). This seems simple.
I create a deep copy of the tree structure and the nodes it contains. Cool.
However, I don't know how to repopulate a new Array with references to these new nodes in this new tree. It seems like it would be simple but I can't figure out how to do it.
I tried to be specific enough to give enough information without being too confusing, hope you understand.
Thanks.
If you're able to change the node data structure, you could add a field for the node's array index. That way, once you've rebuilt your tree you can just walk through it and use the index field to repopulate the array. Not super elegant, but it gets the job done...
Or, to avoid adding a field to your node class, I suppose you could use a temporary hashtable that maps nodes to array indices. Walk through your source array to populate the hashtable, then once you've cloned the tree, walk through the tree, looking up the new nodes in the hashtable (which will work fine assuming you've implemented equals and hashCode properly) and populating the array from those.
Eclipse implements the hashCode() function for a singly linked list's Node class the following way:
class Node{
int val;
Node next;
public Node(int val){
this.val = val;
next = null;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((next == null) ? 0 : next.hashCode());
result = prime * result + val;
return result;
}
}
Now hashCode() for a node is dependent on the hash code of the nodes that follow it.
So, every call of hashCode() will take amortized linear time in the length of the linked list. Thus using a HashSet<Node> will become unfeasible.
One way to get around this is to cache the value of the hashCode in a variable(call it hash) so that it is computed only once. But even in this case, the hash will become invalid once any node's val is changed. And again it will take linear time to modify the hashCode of nodes that follow the current node.
So what are some good ways of implementing hashing for such a linked list Node?
My first thought upon reading your question was: what does LinkedList do? Digging into the source, we see that there is no hashCode() or equals() defined on the inner LinkedList.Node class (link to source).
Why does this make sense? Well, nodes are normally internal data structures, only visible to the list itself. They are not going to be placed into collections or any other data structure where comparing equality and hash-codes are necessary. No external code has access to them.
You say in your question:
Thus using a HashSet<Node> will become unfeasible.
But I would argue that you have no need to place your nodes in such a data structure. By definition, your nodes will link to each other and require no additional classes to facilitate that relationship. And unless you plan to expose this class outside your list (which isn't necessary), they will never end up in a HashSet.
I would propose you follow the LinkedList.Node model and avoid creating these methods on your nodes. The outer list can base its hashcode and equality on the values stored in the nodes (but not the nodes themselves), which is how LinkedList does it - see AbstractList (link to source).
Source links are to the OpenJDK source, but in this case they are identical to source supplied with Oracle JDKs
You have to ask yourself what quality of hashing is valueable for you. The only restriction is to make sure another list with same number in same order has the same hash. That's achieved by using a contant number as well as using the first as well as by limiting on 5 numbers. How much numbers make sense for you depends on the structure of your data. If for example you always store consecutive, ascending numbers starting from 1 and the difference is only the length, that will be hard to optimize. If it's completly random over the entire range of int the first number will do the job well. How many numbers deliver the best ratio for you is found out by measuring I'd say.
In the end what you need is a good ration between collisions (objects put to the same bucket) and calculation time. Generated implementation typically try to maximize the calculation time, providing the human developer with the pleasure of much room for improvement. ;-)
And concerning the changing of contained value: java.util.HashSet (respectivly the HashMap it holds) will calulate its own hash upon yours, and cache that. So if an object containted in a HashSet can't be found again once it changed that far that its hash changed.
In a Java application I need an structure to store, lets call them nodes, and the number of relationship with other nodes. For example, I would need to know that node A is related with B 3 times.
Thinking in a way to implement this I got to this possible solution: Have a hashmap using nodes as key and another hashmap as value. This hashmap would store nodes as key (node B in the example) and an integer as value representing the number of relationships.
What do you think about this? Is it a good approach?
If so, I have a question. Suppose tha I store strings and they come from a text file after apply String.split function. Now I store "hello" in the first hashmap but after processing the file, this string appears as a destiny node in the second hashmap. Would these strings have a reference to the same object or I'll have multiple copies of the same objects?
Regarding the first question, I would do something similar but different. Instead of creating a Hashmap inside a Hashmap I would create a new class Relationship that looks something like this:
public class NodeRelationship {
private Node relatedNode;
private int numOfRelations
// Constructor + getters and setters
}
And define your map like this: Map<Node, List<NodeRelationship>> This seems more readable to me (but maybe it's just me) and easier to later expend. For example if you iterate on the list and want to know the original node you can add a member parent to NodeRelationshio and so on.
Regarding the second question - it depends on how you create your objects and whether you create new objects or use existing ones. If you have a node hello that you put in your value Hashmap (or in the List in my solution) and you use the same object for creating a new key - so there's no duplication. If you don't have a way (or just don't search for) to know that the node was already created, and you create new node - then you'll have duplications of objects.
If indeed your each of your nodes is created from text string, you can maintain a new Map<String, Node> and in the process of reading the file you can maintain this map and check if an object exists before creating a new one. This is very low cost in performance and you can get rid of the map once the construction of the objects from text is done.
I have a large number of objects arranged in a tree-like structure (each node on the tree has parents and children, starting with one master node, and ending in many child nodes). Each object has it's own ID in the form of a string, and there are many duplicate IDs, but no duplicates sunder the same parent. Example:
ParentA:
childA
childB
childD
ParentB:
childA
childC
childD
The tree is also many layers deep.
I need a method of finding objects that will work like this (example is based on the previous list):
Example 1:
an ArrayList with the string {"childB"} is passed to the algorithm
there are no duplicate nodes with an ID of "childB", so a refrence to childB is returned
Example 2:
an ArrayList with the strings {"parentA", "childD"} is passed to the algorithm
there are no duplicate nodes with an ID of "childD" AND a parent with an ID of "parentA", so a reference to the given node is returned
Example 3:
an ArrayList with the string {"childD"} is passed to the algorithm
there are duplicate nodes with an ID of "childD" so the algorithm requests for more information (the name of the parent(s))
Keep in mind that there may be many levels of specificity, like {"nodeA", "nodeD", "nodeX", "nodeD"} so some kind of loop, or maybe a recursive method would be needed.
So, any ideas?
Update:
I created a depth-first-search algorithm to go through each node on the tree, and it works very well. The algorithm returns all nodes in the form of one ArrayList All I need now is a way to select one based on varying degrees of specificity. Can anyone help with that?
The above three examples show what I need.
depth-first search algorithm may be helpful for you!!!