Elegant way to check whether node already in graph - java

I want to check whether a node with a certain ID is already in my graph or whether I have to create a new object. At the moment I am doing it with the following code:
// at this point I have the attributes for the node I need
String id = getIdOfNeededNode(); // The id is used to search for the node in the graph
// now I have to search for the node in the graph
Node node = new Node("dummy_id"); // This is the line I don't like;
// I would prefer not to have a dummy node
// but the compiler will then complain that the node might not be initialized
boolean alreadyCreated = false;
for(Node r : graph.getVertices()){ // search for the node with this id in the graph
if (r.getId().equals(portId)){
node = r;
alreadyCreated = true;
break;
}
}
if (!alreadyCreated) { // create a new object if the node was not found
node = new Resource(portId);
createdPortResources.add(port);
}
// In the remainder of the program, I am working with the node object which then is in the graph
The fact that I am creating a dummy node that is just a placeholder is really ugly. Please let me know how I can solve this problem in a more elegant way.

Well, you can just do this Node node = null;
But in general, just keep a map from the portIds to the nodes.
When you want to make that check, just consult that map.
It will be way easier and faster.

Related

To delete an entire linked list in java which I have created

I want to delete an entire list which I have created in java(note: I am not using internal list in java.util). I have assigned head to null but my question is will the java garbage collector handle the list which has no head or should I delete every node(I mean setting every node to null) which will be handled by java garbage collector? Following is my code, please let me know which one is ok although both works but I would still like to know. Thanks in advance.
//first code
public void deleteList()
{
Node n = head;
Node n1;
head = null;
System.out.println("Deleting list");
while(n != null)
{
n1 = n;
n = n.next;
n1 = null;
}
n1 = n;
n1 = null;
System.out.println("List deleted");
}
//second code
public void deleteList()
{
head = null;
}
It depends on your implementation. If your Node class is internal only (so you don't ever return a Node where it might be saved) and you don't hold any in statics, then there should be no path to any node from a garbage collection root and GC will get rid of them.
So it's probably right, unless your implementation is doing something unusual. (I'm also assuming you don't have a tail variable or anything else that references an internal Node, because those would also need to be set to null).
The Garbage Collector will destroy an object only when the particular object doesn't have any linked internal dependency to other nodes. In other words, whenever the objects are not referenced anymore, they are destroyed and their memory is reclaimed.
your first code is right, when you have internal dependency with other nodes i.e, tail node, for example.
your second is right, when you doesn't have any dependency with other node.

Setting Head in a Linked List

I am trying to make a Linked List I have a working insert method however I don't know how to set head to the front of the list.
public void insert(Object o) {
curr = new Link(o,curr);
if(ticker ==0){
head = curr;
tail = curr;
}
ticker++;
}
This just sets head to the end of the list when it needs to be in the front. Any help would be much appreciated. And if you need anything else to figure this out let me know.
I don't exactly know what your Link is, but I think you should create a Node class like
class Node {
Object value;
Node next;
Node pre; // optional
}
And your head and tail will be a instance of Node.
I think your problem lies in the constructor for Link. Based on your result, the new Link stores a reference to the old Link; this is reversed, and thus your list is built in reverse. Set the Link argument's next node to the Link being instantiated, something like
public Link(Object value, Link previous) {
...
previous.nextLink = this;
...
}
The head of a linked list refers to the first element that was added, not the last, as you indicated in your comment. That's just the terminology.
You need an else branch in your insert method setting tail = current, so you always have a reference to the end of the list. (head already points to the beginning of the list, and which node is the head won't change) In fact, if you do this, you won't even need the variable tail, since current will serve the same purpose.

Dynamically add nodes in a JTree

I have data like this (has other data like percentage, but is not important now) in a List that can vary:
1
1.1
1.1.1
1.1.2
1.2
2
2.1
2.2
How i easily work with the levels to build a proper JTree for any given levels?
Can be done with recursion?
What the best way?
Thank you so much.
Yes, it can easily be done using recursion. The idea is to check if there is already a node in the tree under which the new node can be fallen. For example, if the new node is "1.1.2", then we have to check if the node "1.1" exists in the tree. I wrote a very simple code and it is working, I am going yo cope here. If you don't understand something then just let me know, I will explain you. The function to check if the tree has the node of a particular string is given below.
public DefaultMutableTreeNode findparentnode(String s,DefaultMutableTreeNode root){
DefaultMutableTreeNode parent=null;
for (int i=0;i<root.getChildCount();i++) {
if(s.equalsIgnoreCase(((DefaultMutableTreeNode)root.getChildAt(i)).toString())){
parent = (DefaultMutableTreeNode)root.getChildAt(i);
break;
}
else
parent=findparentnode(s, (DefaultMutableTreeNode)root.getChildAt(i));
}
return parent;
}
Now, we will check every string in the list. We will skip the last part of the string, and will pass the remaining value to the function. To check the string, the code is given below
for(String s:list){
String[] substr=s.split("\\.");
String parent=substr[0];
for(int i=1;i<substr.length-1;i++){
parent=parent+ "." + substr[i];
}
DefaultMutableTreeNode node=null;
node=findparentnode(parent,root);
if(node==null)
root.add(new DefaultMutableTreeNode(s));
else
node.add(new DefaultMutableTreeNode(s));
}

Java: How to create a queue based on a Node class

I'm trying to create a queue using two classes, a Node class and a Queue class for an assignment. Here's the node class:
class Node
{
protected Node next;
public Node()
{
next = null;
}
}
This class basically links the data together using a Node.next object. I've successfully been able to create a stack with push() and pop(), because the two operations happen on the same end, so the point are just manipulated between pointing to a new added node, and the previous node.
However, I'm having some difficulties understanding the logic to create a queue based on a similar structure. My queue class looks something like this:
class Queue
{
private Node footer;
private Node header;
public Queue()
{
footer = null;
header = null;
}
public void add(Node newNode)
{
//Adds onto the queue from the 'footer' end.
}
public Node remove()
{
//Removes from the queue from the 'header' end.
}
Here's what I understand: (1)The header and the footer point to the same first node. (2) Subsequent adding should change the footer to point to the added nodes, but the header stays on the first node added. (3) The header should point to the next oldest node upon removal.
Here's what I can't figure out (and where it's different than popping from a stack). How do I get the header to point to the 'next oldest node', given that I have more than 2 nodes in this queue? I know I can do this if I link header.next to the next node in the queue, but how can I access the next node so that it can point to it?
I thought about how in add(), the newNode.next should point to the next newNode (reverse direction of a Stack), but this can't work because the next newNode isn't in existence yet.. Another idea was to modify the Node class to have a Node.previous for a way to point backwards, but I would be breaking specification for this assignment.
My instructor hinted something about "header.next will point for second item as header and footer point to first node initially," and that the way to do this is pretty simple. However, I've been drawing how this works, and I'm confused how the initial pointing to the same node will allow header.next to "automatically" point to the next oldest node, especially if more and more nodes are added and the footer eventually is separated from the header by more than 2 nodes. Is there something about OOP I'm not seeing?
Any help would be great!
To expand on, and offer a subtle alternative to #Sanjeev's answer (one that I think your instructor was hinting to):
Rather than using footer to store "actual" nodes, use it as a placeholder: Declare it as a final variable, initialize it in your constructor and make sure that either a) it's next node is always your header (this would be called a circular list), or its next node is null.
Can you see how this solves your "this can't work because the next newNode isn't in existence yet" problem: Of course you can't point the last node added to the next one that will be added before adding it - instead, you point it to this "dummy" node - which is a placeholder for the next node that will be added, when and if it is.
add(Node newestNode){
identify the last node added as the one whose next property is the footer.
change the next property of that node from footer to this new newestNode
set the next property of this new newestNode to footer
}
It would be preferable to identify that last node added as the one that footer is pointing to (rather than the one pointing to footer), which would be easy if you were allowed to have previous as well as next properties on nodes, but it sounds like you're not allowed to do that. Of course, since we're using footer as a "dummy node", we could simply use footer.next the way we would footer.previous and have it point backwards instead of forwards, but I'll leave you to consider how clean that would be. There are other options here that I'll leave you to consider as well.
How do I get the header to point to the 'next oldest node'`
The "oldest" node was the first one added. The "newest" node is the last one added. How is the order of the rest of the nodes stored? The same way it was in your Stack - by traversing a chain of references stored as instance variables on your nodes. The main point I want to make is that Stacks and Queues, when implemented as linked data structures, are much more similar than you seem to be thinking, at least from a : Iterating through any linked data structure is done by following traversing these links - don't get too hung up on the fact that you're "moving" in a different direction - the same basic principles apply:
Node remove(){
identify the "oldest" node as header.next.
Store a reference to that node so you can return it.
identify the "second oldest node" as header.next.next
change header.next to header.next.next
return the reference to the old header.next you saved above.
(Note that using header/footer as placeholders, rather than storing "actual" nodes in them as #Sanjeev suggests, is not necessary, but it'll make your life easier - for instance, by helping you avoid a lot of null checking)
Here is the sudo code that will help you get started.
public void add(Node newNode)
{
if footer is null ?
then
header = newNode and footer = newNode;
else
footer.next = newNode and footer = newNode;
end if
}
public Node remove()
{
Node returnMe = header;
if header is not null?
then
header = header.next
if header is null
then
footer = null;
endif
end if
return returnMe;
}
How do I get the header to point to the 'next oldest node', given that
I have more than 2 nodes in this queue? I know I can do this if I link
header.next to the next node in the queue, but how can I access the
next node so that it can point to it?
To make header point to that node, you only need do header = header.next. The reason is that Java objectt assignment is by reference. Since header.next is type of Node, header is type of Node, it will copy the address of header.next to header, i.e., header is advanced one place.
I thought about how in add(), the newNode.next should point to the
next newNode (reverse direction of a Stack), but this can't work
because the next newNode isn't in existence yet..
I think it is no need to considering reverse direction. The reason is because for adding , it is to add element to the tail/footer of the queue. The only special case is that the queue didn't have any elements (footer == header == null), 1 element : (footer = header = element), other case: header won't change, but you need to append element to footer, and then make footer point to the new node.
When only 1 element, footer.next == header.next == null
The first thing that you need to do is make sure the first node you create is the oldest so it should be the first to be removed from the Queue based on First In First Out (FIFO) principle to archive this you might need to modify you're add method to something like this, by the way this example is based on single linked list implementation.
void add(char new_data)
{
/* 1. alloc the Node and put data*/
Node new_Node = new Node(new_data);
/* 2. Make next of new Node as head */
new_Node.next = head;
/* 3. Move the head to point to new Node */
head = new_Node;
}
then you will need a remove method which will remove the oldest node on the list first remember in Queue the order of remove is First In First Out (FIFO)
that being said this remove method should help you
void remove()
{
// Store head node
Node temp = head, prev = null;
// If head node itself holds the key to be deleted
if (temp != null )
{
head = temp.next; // Changed head
return;
}
// Search for the key to be deleted, keep track of the
// previous node as we need to change temp.next
while (temp != null)
{
prev = temp;
temp = temp.next;
}
// If key was not present in linked list
if (temp == null) return;
// Unlink the node from linked list
prev.next = temp.next;
}
This worked for me on my linked list

Threaded Binary tree implementation from binary tree

I am working on assignment for school. It manly consists of a method that takes as input a binary tree and returns a double threaded tree. Eg(if left child = null then left child will be connected with preceding inorder parent and if right child = null the it will link to its inorder succesor. Now I have an idea for the implementation...
I iterate recursively trough the original BINARY tree and store into an array the inorder traversal. Now, because my teachers implementation requires that threaded trees be a different class from binary. I must traverse again trough the binary tree and convert each node from binaryNode to threadedNode thus having at the end a "duplicate" of the initial BinaryTree but as Threadedtree type. After I do this I traverse again trough this threadedTree and whenever i see a null left or right child I refer to the inorder arraylist and find the threads.
Now as you might have noticed this is extremely inefficient, i am essentially traversing the tree 3 times. My professor has stated that this could be done recursively with only one traversal, essentially converting to threadedNode and finding the threads all at once. I have tried multiple ways but i can not find one that works. Does anyone have any kind of tip or some way i can implement it? Thanks
This is the method as specified by the instructor
public static <T> ThreadedNode<T> thread(BinaryNode<T> root)
{
//threads a binary tree
}
The instructor is correct. One traversal is sufficient.
Traverse the original binary tree, creating new ThreadedNodes as you walk this tree.
public static <T> ThreadedNode<T> thread(BinaryNode<T> root) {
// We'll be keeping track of the "previous" node as we go, so use
// a recursive helper method. At first, there is no previous.
return threadHelper(root, null);
}
private static <T> ThreadedNode<T> threadHelper(BinaryNode<T> n, ThreadedNode<T> previous) {
// Create a new threaded node from the current root. Note that the threaded nodes
// are actually created in "preorder". Assume the ThreadedNode constructor sets
// the left, right, threadLeft, and threadRight fields to null.
ThreadedNode<T> t = new ThreadedNode<T>(n.getData());
// First go down the left side, if necessary.
if (n.getLeft() != null) {
// If there is a left child we have to descend. Note that as we go down the
// left side the previous doesn't change, until we start "backing up".
t.left = threadHelper(n.getLeft(), previous);
previous = t.left;
} else {
// If there is no left child, connect our left thread to the previous.
t.threadLeft = previous;
}
// Now before we go down the right side, see if the previous
// node (it will be in the left subtree) needs to point here.
if (previous != null && previous.right == null) {
previous.threadRight = t;
}
if (n.getRight() != null) {
// If there is a right child we can descend the right. As we go down we
// update previous to the current node. We do this just by passing the current
// node as the second parameter.
t.right = threadHelper(n.getRight(), t);
} else {
// No right child, no worries. We'll hook up our thread-right pointer
// later.
}
return t;
}
Consider the tree (A (B (D) ()) C). The first node you hit in an inorder traversal is D. There is no previous node. So save D as previous. Then the next node you hit is B. The previous node was D, which had no right child, so add a threaded right pointer from D to B. Then set previous to B and continue. Next you hit A. B had no right child, so add a threaded right link from B to A. A has a right child so continue, setting previous to A. The next node is C. C has no left child, so add a threaded left link from C to the current value of previous, which is A.
You could skip the second trip of traversal that you mention in your method. You could convert the nodes from BinaryNode to ThreadedNode on the fly. You'd still need to traverse twice, I think, for the inorder traversal, and for finding the threads and converting it to aThreadedTree.
For conversion on the fly, you could use the method that your instructor has given.
HTH!

Categories

Resources