In red-black tree, when rotate, you need to know who is the parent of particular node.
However, the node only has reference to either right or left child.
I was thinking to give a node instance variable "parent" but just for this reason I don't think it is worth doing so and also it would be too complicated to change parent reference per rotation.
public class Node {
private left;
private right;
private isRed;
private parent; //I don't think this is good idea
}
So, my solution is to write findParent() method that use search to find parent. I am wondering if there is any other way to find a node's parent?
My solution:
sample tree:
50
/ \
25 75
If you want to find parent of Node 25, you pass something like:
Node parent = findParent(Node25.value);
and it returns node50.
protected Node findParent(int val) {
if(root == null) {
return null;
}
Node current = root;
Node parent = current;
while(true) {
if(current.val == val) { //found
return parent;
}
if(current == null) { //not found
return null;
}
parent = current;
if(current.val > val) { //go left
current = current.left;
}
else { //go right
current = current.right;
}
}
}
The use of a parent pointer is optional. If you forgo the parent pointer then you will have to write insert/delete operations using recursion (the recursive method calls preserve the parent information on the stack) or write an iterative version which maintains its own stack of parents as it moves down the tree.
A very good description of red-black trees can be found here
http://adtinfo.org/
That includes descriptions of a number of rbtree implementations including with and without parent pointers.
If you do want to save on space (and that is fair enough) a really excellent description of an rbtree implementation can be found here
http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
The method you have described for searching for a node's parent would be very inefficient if used by the insert/delete implementations. Use a pointer or use recursion.
I was thinking to give a node instance variable "parent" but just for this reason I don't think it is worth doing so
Having your nodes have a parent reference requires one extra pointer/reference per node. Compare this with needing to traverse the tree whenever you need to know the parent for a given node.
This is then a trade-off between
The cost of maintaining an extra reference, and keeping it up to date whenever you modify a node.
The computational cost and complexity of having to traverse the tree to find a parent of a given node
I think that the choice between these two options is somewhat subjective but personally I would choose to simply keep track of the parent references.
As a point of reference for you, java.util.TreeMap is implemented as a Red-Black tree which Entry nodes that contain left, right, and parent references.
As you traverse the tree to get to your pivot node you can cache the previous parent or if you need more than one level of "undo" you could cache each traversed node on to a stack.
This cache would be a variable local to your rotation algorithm so it wouldn't require any more space in the tree or expensive additional traversals.
It's definitely better to store the parent than to look it up. Updating parent reference is not that complex.
Another solution, besides parent pointers and querying the parent all over again is to maintain an ancestor stack.
Suppose someone wishes to insert 23 into the following tree:
Red Black Tree
Generally the algorithm to insert is:
Find node where 23 would be if it is in the tree
If 23 is already there, return failure
If 23 is not already there, put it there.
Run your re-balancing/coloring routine as needed.
Now, to use the stack approach, you allocate a stack big enough to support one node per level of your tree (I think 2 * Ceiling(Log2(count)) + 2) should have you covered. You could even keep a stack allocated for insertion or deletion and just clear it whenever you start an insertion.
So -- Look at the root. Push it onto the stack. 23 is greater than value in the root, so go right. Now push node current node (value 21) onto the stack. If 23 is in the tree, it must be to the right of current node. But the node to the right of the current node is a null-sentinel. Thus, that null-sentinel should be replaced with a node with your value. The parent is the item on the top of the stack (most recently pushed), the grandparent is next in line ... etc. Since you seem to be learning ... Java supplies a stack interface for you so you won't need to develop your own stack to do this. Just use theirs.
As to whether this is better than the parent pointer approach, that seems debatable to me -- I would lean to the parent pointer approach for simplicity and elimination of the need to maintain an ancillary data structure or use recursion extensively. That said, either approach is better than querying the parent of the current node as you apply your re-balancing/coloring routine.
Related
Once you've gotten a node from the JCR, what is the easiest way to get its previous and next siblings?
Not entirely sure if its the easiest way but you may do something like that
Node parent = node.getParent();
NodeIterator siblings = parent.getNodes();
Node firstSibling = siblings.nextNode();
For previous you should do some operations on siblings object but that should be straightforward. This would be the JCR way of doing that.
However, Magnolia has the helper functions which reside under info.magnolia.jcr.util.NodeUtil package
Then One may use the following;
NodeUtil#getSiblingBefore()
NodeUtil#getSiblingAfter()
Problem is I don't understand how to create a tree. I have gone through many code examples on trees but I don't even know how to work with/handle a node and hence I don't understand how the node class works(that was present in all the program examples ). When i try to use methods such as appendChild(as mentioned in java docs),I get an error,and I am asked to create one such appendChild method inside that node class within the main program. Couldn't understand why that happened.
I am given integer pairs((u,v) meaning there is an edge between u & v) of nodes and I also need to know if any Element-to-node conversion is required for using u and v(of type integer) as nodes.
Please bear with me since my basics are weak. Little explanation on how the entire thing works/functions would be very helpful.
Thank you.
EDIT 1: I went through the following links:(hardly found anything on just unordered trees) http://www.cs.cmu.edu/~adamchik/15-121/lectures/Trees/code/BST.java http://www.newthinktank.com/2013/03/binary-tree-in-java/ . Tried to modify these codes to meet my own purpose but failed.
I only got a blurry idea and that is not enough for implementation. I am trying to make a simple unordered tree,for which i am given u v pairs like:
(4,5) (5,7) (5,6). I just need to join (4<--5),(5<--7) and (5<--6). So how do I write a node class that only joins one node to the prev node? Besides,to do only this,do I need to bother myself with leftchild,rightchild? If not,how will I be able to traverse the tree and do similar operations such as height diameter calculation etc later?
Thank you for your patience.
Well Its not entirely clear whether you want an explanation on tree creation in general, on some tree implementation you have found, or you have a basic code already that you cannot get working. You might want to clarify that :).
Also tree creation in general:
Most explanation and implementation you will find might be "overly" elegant :). So try to imagine a simple linked list first. In that list you have nodes(the elements of the list). A node contains some valuable data and a reference to an other node object. A very simple tree is different only in that a node have more than one reference to other nodes. For example it has a Set of references, its "children".
Here is a VERY crude code only as an example for addChild() or appendChild in your case:
public class Node {
private String valueableData;
private Set<Node> children;
public Node(){
this.children=new HashSet<Node>();
}
public Node (String valueableData){
this.valueableData=valueableData;
this.children=new HashSet<Node>();
}
public void addChild(Node node){
children.add(node);
}
}
Now this implementation would be quite horrible (I even deleted the setter/getters), also it would be wise to keep the root nodes reference in some cases, and so on. But you might get the basic idea.
You might wanna create a cycle or recursion to go over the (u,v) integer pairs. You create the root node first then you just addChild() all the other nodes recursively, or create every node first then setChild() them according to your rules.
I am implementing a PriorityQueue in my program. For that I have also implemented compareTo(). The compareTo() is being called when I perform add(), which is expected. But it is also called when I perform poll(). I thought that the function of poll() is just to remove the head. Why does it need to call compareTo()?
The way a priority queue is implemented is often done with a heap. Part of poll()ing requires restructuring the heap which requires the heap to compare elements... hence compareTo(). This is just a guess though (i.e. I have not dug into the source code to verify my claim).
Here's a quick search on how priority queues are implemented using heaps if you are interested: http://pages.cs.wisc.edu/~vernon/cs367/notes/11.PRIORITY-Q.html#imp
Actually just for fun I'll describe how this works in a non-rigorous fashion. A heap is a tree satisfying the heap property: parents are always less than or equal to their children (min heap) or parents are always at least as large as their children (max heap). PriorityQueue is a minheap so poll() removes the root (make sure you understand this). But what happens to the tree if you remove the root? It's no longer a tree... So the way they fix this is by moving the root of the tree to a leaf node (where it can be plucked without destroying the tree/invalidating the heap property), and putting some other node in the root. But which node do you put into the root? Intuitively you might think they'd put the left or right child of the root (those are "almost as small as the original root"). You can do that, but you'd then need to fix the subtree rooted at that child (and the code is ugly). Instead they do the same thing (conceptually) but do it slightly differently to make the code nicer. In particular, they pluck a leaf node and stick it in the root (generally you swap the root and the leaf node to do both steps simultaneously). However, the heap property is no longer necessarily satisfied (the leaf node we stuck in the root could be quite large!). To fix this, you "bubble down" the new root until you get it to its correct location. Specifically, you compare the new root with the left and right children and keep swapping (if the parent is larger than at least one of the children) until the heap property is satisfied. Notice that this swapping will indeed lead to a valid heap (you can prove this, but it's intuitive).
Everything is in the JavaDoc (emphasis mine):
An unbounded priority queue based on a priority heap.
And in the source code of poll() you'll find:
public E poll() {
//...
if (s != 0)
siftDown(0, x);
return result;
}
Where siftDown() is:
/**
* Inserts item x at position k, maintaining heap invariant by
* demoting x down the tree repeatedly until it is less than or
* equal to its children or is a leaf.
* [...]
*/
private void siftDown(int k, E x) {
if (comparator != null)
siftDownUsingComparator(k, x);
else
siftDownComparable(k, x);
}
The JavaDoc comment on siftDown() is crucial, read it carefully. Basically the undeerlying implementation of PriorityQueue uses a heap which has to be restructured every time you modify it by polling.
Why are you bothered by this? compareTo() should be lightweight, idempotent and side-effect free method, like equals(). You shouldn't put any restrictions on it.
I did a search on similar topics, but the answers are too vague for my level of understanding and comprehension, and I don't think they're specific enough to my question.
Similar threads:
Tree (directed acyclic graph) implementation
Representing a DAG (directed acyclic graph)
Question:
I have formatted a text file which contains data of the following format...
Example dataset:
GO:0000109#is_a: GO:0000110#is_a: GO:0000111#is_a: GO:0000112#is_a: GO:0000113#is_a: GO:0070312#is_a: GO:0070522#is_a: GO:0070912#is_a: GO:0070913#is_a: GO:0071942#part_of: GO:0008622
GO:0000112#part_of: GO:0000442
GO:0000118#is_a: GO:0016581#is_a: GO:0034967#is_a: GO:0070210#is_a: GO:0070211#is_a: GO:0070822#is_a: GO:0070823#is_a: GO:0070824
GO:0000120#is_a: GO:0000500#is_a: GO:0005668#is_a: GO:0070860
GO:0000123#is_a: GO:0005671#is_a: GO:0043189#is_a: GO:0070461#is_a: GO:0070775#is_a: GO:0072487
GO:0000126#is_a: GO:0034732#is_a: GO:0034733
GO:0000127#part_of: GO:0034734#part_of: GO:0034735
GO:0000133#is_a: GO:0031560#is_a: GO:0031561#is_a: GO:0031562#is_a: GO:0031563#part_of: GO:0031500
GO:0000137#part_of: GO:0000136
I'm looking to construct a weighted directed DAG from this data (the above is just a snippet). The whole dataset of 106kb is here: Source
--------------------------------------------------
Taking into consideration line-by-line, the data of each line is explained as follows...
First line as an example:
GO:0000109#is_a: GO:0000110#is_a: GO:0000111#is_a: GO:0000112#is_a: GO:0000113#is_a: GO:0070312#is_a: GO:0070522#is_a: GO:0070912#is_a: GO:0070913#is_a: GO:0071942#part_of: GO:0008622
'#' is the delimeter/tokenizer for the line data.
The First term, GO:0000109 is the node name.
The subsequent terms of is_a: GO:xxxxxxx OR part_of: GO:xxxxxxx are the nodes which are connected to GO:0000109.
Some of the subsequent terms have connections too, as depicted in the dataset.
When it is is_a, the weight of the edge is 0.8.
When it is part_of, the weight of the edge is 0.6.
--------------------------------------------------
I have Google-d on how DAGs are, and I understand the concept. However, I still have no idea how to put it into code. I'm using Java.
From my understanding, a graph generally consists of nodes and arcs. Does this graph require an adjacency list to determine the direction of the connection? If so, I'm not sure how to combine the graph and adjacency list to communicate with each other.
After constructing the graph, my secondary goal is to find out the degree of each node from the root node. There is a root node in the dataset.
For illustration, I have drawn out a sample of the connection of the first line of data below:
Image Link
I hope you guys understand what I'm trying to achieve here. Thanks for looking through my problem. :)
Because it's easier to think about, I'd prefer to represent it as a tree. (Also makes it easier to traverse the map and keep intermediate degrees.)
You could have a Node class, which would have a Collection of child Node objects. If you must, you could also represent the child relationships as a Relationship object, which would have both a weight and a Node pointer, and you could store a Collection of Relationship objects.
Then you could do a walk on the tree starting from the root, and mark each visited node with its degree.
class Node{
String name;
List<Relationship> children;
}
class Relationship{
Node child;
double weight;
}
class Tree{
Node root;
}
Here, Tree should probably have a method like this:
public Node findNodeByName(String name);
And Node should probably have a method like this:
public void addChild(Node n, double weight);
Then, as you parse each line, you call Tree.findNodeByName() to find the matching node (and create one if none exists... but that shouldn't happen, if your data is good), and append the subsequent items on the line to that node.
As you've pointed out, DAGs cannot really be converted to trees, especially because some nodes have multiple parents. What you can do is insert the same node as the child of multiple parents, perhaps using a hash table to decide if a particular node has been traversed or not.
Reading the comments, you seem confused by how a Node can contain Relationships which each in turn contains a Node. This is quite a common strategy, it is in general called the Composite pattern.
The idea in the case of trees is that the tree can be thought of as consisting of multiple subtrees - if you were to disconnect a node and all its ancestors from the tree, the disconnected nodes would still make a tree, though a smaller one. Thus, a natural way to represent a tree is to have each Node contain other Nodes as children. This approach lets you do many things recursively, which in the case of trees is often, again, natural.
Letting a Node keep track of its children and no other parts of the tree also emulates the mathematical directed graph - each vertex is "aware" only of its edges and nothing else.
Example recursive tree implementation
For instance, to search for an element in a binary search tree, you would call the root's search method. The root then checks whether the sought element is equal, less or greater than itself. If it is equal, the search exits with an appropriate return value. If it is less or greater, the root would instead call search on the left or right child, respectively, and they would do exactly the same thing.
Analogously, to add a new Node to the tree, you would call the root's add method with the new node as a parameter. The root decides whether it should adopt the new node or pass it on to one of its children. In the latter case, it would select a child and call its add method with the new Node as a parameter.
I've got a set of TreeNodes, each of which has an id, a Collection of parent nodes, and a collection of child nodes.
For a given node Id, I'm looking for an efficient way to generate all the links that pass through that node. So in short, start at the node, and iterate through all its children. If a node has more than one child, create a link for each child. The traverse the children etc..
I'd also like to be able to do this in an 'upward' direction, through the parent nodes.
Is there a simple algorithm to do this?
EDIT: Oh, and I'd like to be able to output the id's of all the nodes in a given chain...
You are looking for a Breadth First or Depth First Search. At first it is not more than the following (this is depth first search).
Visit(Node node)
{
foreach (Node childNode in node.Children)
{
Visit(childNode);
}
DoStuff(node);
}
The problem is that the graph may contain cycles, hence the algorithm will enter infinite loops. To get around this you must remember visited nodes by flaging them or storing them in a collection. If the graph has no cycles - for example if it is a tree - this short algorithm will already work.
And by the way, if a TreeNode has multiple parents, it's not a tree but a graph node.
Well, if the nodes have a reference to the parent, it's simple as getting the parent recursively (once in a tree, each node has only one (or none at all, if it is a root) parent.
If there's no such reference, than you could use a breadth-first search, for instance, having as initial set your collection of parent nodes.
-- EDIT --
Once a node may have more than one parent, then you're dealing with a graph. There are also graph traversal algorithms (see table at the side).
Make sure that, if your graph has a cycle, you won't end up having a infinite loop
You might want to check out depthFirstEnumeration() and breadthFirstEnumeration() on DefaultMutableTreeNode. However, this doesn't solve your problem of wanting to navigate the tree in a bottom-up fashion.