My implementation of the collection is as follows:
private void init(Node<K, E> root) {
Node<K,E> node = root;
while (node != null) {
stack.push(node);
node = node.getLeft();
}
}
However when it gets invoked and used, it seems that there is nothing in the Stack. I've tried debugging exhaustively without any avail, any suggestions as to what might be going wrong in the way I implemented the above components?
You've made your Stacks immutable. When you call the push() method, it doesn't actually push the node on to the stack, it returns a new immutable Stack with that element pushed on to it. When calling all modifying methods such as push and pop, prepend stack = on the line to assign the newly returned stack back to stack.
E.g. replace
stack.push(node);
with
stack = stack.push(node);
Related
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.
I have this recursive function that is supposed to delete the node that comes after the specified one in
a doubly linked list. However My method Isn't deleting anything. I am having trouble with rearranging the values in the list. Any ideas?
private void deleteAfterThis(T data, Node headAux) {
if(headAux == null) {
return;
}
Node deleteAfter = new Node(data);
Node target = deleteAfter.next;
if(target == null) {
return;
}
if(deleteAfter.prev == null){
if(target != tail && target==headAux) {
deleteAfter.next = target.next;
target.next.prev = deleteAfter;
size--;
deleteAfterThis(data, headAux.next);
}
else if(target == tail && target == headAux) {
deleteAfter.next = null;
deleteAfter = tail;
size--;
return;
}
}
else if(deleteAfter.prev != null) {
if(target != tail && target == headAux) {
deleteAfter.next = target.next;
target.next.prev = deleteAfter;
size--;
deleteAfterThis(data, headAux.next);
}
else if( target == tail && target == headAux) {
deleteAfter.next = null;
deleteAfter = tail;
size--;
return;
}
}
deleteAfterThis(data, headAux.next);
}
One mistake I see right off the bat is that you should not be creating a completely new node for deleteAfter. Intuitively, does it make sense to have to create a new node when attempting to delete one? I'll assume that, even knowing what the constructor for Node actually looks like, it sets the next and prev pointers to nodes to null. As a result, you'll keep recursively updating headAux until it's null without ever deleting anything. It seems what you want deleteAfter to be is headAux.next.
Another bug I see is that you've copy and pasted your checking logic twice - I recommend stepping through both cases and verifying if the logic should be identical within each block of the if and else-if blocks (it probably shouldn't).
Stepping into the logic, you should realize that the prev node of the current (headAux in your code) would be null only if headAux is the head of the list. Thus, it would be a bit more clear to rewrite the headAux.prev check as verifying if headAux is equal to the head of the linked list.
Looking at the actual deletion logic, it seems to make sense in the general case to me (assuming the fact that deleteAfter is the next node of headAux as stated above). You're making the prev of the node to be deleted to point to the deleted node's prev node and the next of the previous node (after having set the pointer, which I'm not too big of a fan of but it works) point to deleteAfter.
Lastly, when you do actually locate the node you'd like to delete, you probably shouldn't be calling the recursive function again. You already handle the setting of pointers correctly, so there shouldn't be a need to do so.
I would highly recommend you (re-)draw a sample use-case of your circular linked list and perform deletion on a sheet of paper before jumping to coding the edgecases (which aren't all handled here). The edge cases you should probably be aware of are the following: empty list, deleting head, deleting tail, single-node list. In your code, it seems that you did try to handle the deletion of the head (you'd have to remember to set the head afterwards). After getting that to work, making deletion work on other cases should be a breeze.
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
I have written a code for deleting all elements of tree.
Need suggestions for following:
In reverseTreeStack method, Can I design without using stack method parameter?
Can I design the entire code in 1 method with better design?
UPDATE : Changed return type of reverseTreeStack to void.Removed additional variable for stack.
public class DeleteTree {
public static void deleteTree(BinaryTreeNode root)
{
Stack stack = new Stack();
reverseTreeStack(stack, root);
while (!stack.isEmpty())
{
BinaryTreeNode node = (BinaryTreeNode)stack.pop();
System.out.println("---------Deleting----------->" + node.getData());
node = null;
}
}
public static void reverseTreeStack(Stack stack,BinaryTreeNode root)
{
if (root != null)
{
stack.push(root);
reverseTreeStack(stack,root.getLeft());
reverseTreeStack(stack, root.getRight());
}
}
}
Why do you need to do this? If I recall correctly, the JVM can free resources once there are no available references to the resource, so just setting your root node to be null should free the whole tree.
I think, James is right, but if you want to practice the tree traversal, or if you want to implement this in a language where you need to free memory manually, then use recursion:
void deleteTree(TreeNode node)
{
if(node==null)return;
deleteTree(node.getLeft());
deleteTree(node.getRight());
System.out.printline("Deleting: "+node.getData())
node = null;
}
Also take a look at Postorder Traversal (thats the only one, that works for deleting)
1) I think you can kill the return value and make it a void method as you are directly manipulating the stack. So just do
Stack stack = new Stack();
reverseTreeStack(stack, root);
// Now just use stack
2) Don't condense things into one method. Breaking things out into more methods will make your code easier to navigate and understand. The less each function is responsible for, the more sense it will make to someone reading it.
Well your reverseTreeStack method can potentially give you a StackOverflowError if your tree is too large, so using a loop instead of recursion there might be a better choice (unless you know for a fact that your trees will never be that large).
Also, why are you "deleting" every node? (node = null actually just removes the reference you have just in that method...) Generally just forgetting the root (root = null) will delete your whole tree if you're structuring it in the classic way of Node(parent, leftChild, rightChild) and not storing pointers to nodes anywhere else.
I need to write my own Deque class and must used a doublylinked list implementation to store data. the problem is writing the method pushfromLeft(Thing thing) which will insert into the left side of the deque. Below is what I have thus far but does not seem to work.
public void pushLeft(Thing thing) {
Node beg = new Node();
Node end = new Node();
Node T = new Node();
if(isEmpty())
{
beg = first;
end = last;
beg = end;
T = beg.thing;
N++;
}
else
{
beg = beg.next;
end = end.next;
T = beg.previous;
N++;
}
Little you do in that method has any effect outside, except changing N and item. Presumably you should be modifying first. It would help if you provide the fields of your class, and what they mean, for context. For instance, it's not clear what item is.
You should also either come up with different conventions for naming member and local variables, or consistently use this., or both.
Might I make a suggestion that may clear a lot of this up for you. it's not what you asked for, but it may be what you need.
Use OO design, this means not operating on something but asking something to operate on itself. What this means is that Node should be more intelligent--currently you are acting on node.
Since Node is doubly linked, it can be pretty smart! It can have methods like:
newNode.insertBefore(currentNode)
newNode.insertAfter(currentNode)
currentNode.remove()
Once you have those, the rest of your code should clean up a bit. They should be trivial to implement given a doubly linked list.
void insertBefore(node existing) {
// first set my stuff up
previous = existing.previous;
next = existing;
// then point other stuff at me
previous.next = this;
existing.previous = this;
}
I think--that's just off the top of my head.
The other question is how do you handle your "Endpoints". Your first and last pointers have to be instances of Node for this to work, but if they are notice that the whole "If" factors out of your original code! Sweet!
Just ALWAYS have a first and last object that start out pointing to each other (and never take on values). When you do your first add, do first.insertAfter() or last.insertBefore() and you are done.
Another possibility, by the way, is to make the list circular--there is no reason that First and Last couldn't be the same "Special" unassigned node, you could still traverse it's Next (which will give you the first real item in the list) and Previous (giving you the last item in your list).
When iterating the entire list, if .value == null, you know you've made it to the other end which makes node.next() and previous() fascinatingly easy to implement (You don't really even need to implement .next, but see below.
/** returns null if there are no more items in the list */
Node next() {
return next;
}
Try it, it will simplify your code a LOT. Most people really don't get how useful actual OO code is.
Also, make all your variables private, it's a good habit to get into. In this case when you are having nodes operate on each other, they can still access each other's private members (not as dirty as it sounds) so you can still have the insertBefore as I wrote it AND you don't have to have getters and setters or public variables. Best of both worlds.
Also notice how your original class that "Operated" on node all but disappears--in fact, it can go away completely. If you needed some specific methods like find(item) or insertSorted(item) there is no reason you couldn't add them to node itself. This may be hard to see until after you implemented it though.
Funny how if you actually code well, most of the complaints people have about Java just don't come up.
Have you looked at the LinkedList source code as a reference?
You definitly don't need to create more than one Node inside adding method. If you want to read from left AND from right later, each Node must remember previous and next element. Then when adding, you just need to re-locate these links, like this:
public void pushLeft(Thing thing) {
Node newNode = new Node();
newNode.setValue(thing); //or just newNode.value = thing;
if(this.isEmpty())
{
this.first = this.last = newNode;
this.n=1;
}
else
{
this.first.previous = newNode;
newNode.next = this.first;
this.first = newNode;
this.n++;
}
}
It vould be wise to create a constuctor for Node class which shoul automaticaly set the value, then you can just wite:
Node newNode = new Node(thing);