Remove Method in HashTable - java

Hi I'm working on an assignment about hash table. Everything is fine except for the remove method.
Here's code:
public boolean remove(K key) throws HashTableException {
//
//IMPLEMENT THIS FUNCTION
//
if (key == null)
throw new HashTableException("Null keys not allowed in the hash table");
int index = getIndex(key);
HashTableNode<K,V> node = FindNode(key,index);
if (node == null) {
return false;
} else {
if (node.getNext() == null) {
node = null;
} else {
node = node.getNext();
}
return true;
}
}
It doesn't remove the key at all. Can anyone help me please? thank you!

node = null; does not "delete" the node, it just sets the value of the variable node in this method to null. It does nothing to the actual node that is in the hashtable somewhere.
And in the next "else" you then have node = node.getNext(); which, again, only change the node variable in this method. But since you return from the method without doing anything more with this variable, all this does is nothing since node is a local variable that only exists in this method.
You should read up on the concepts of local variables and references in java, which would probably lead to an understanding of why this is not working :)

node = node.getNext();
By this line, I think you are just traversing instead of re-writing the Next pointer
Maybe you should try node.getPrev().setNext = node.getNext();
if you can find the previous node and be able to set the next node.

Please make sure hashcode() and equals() are overridden correctly.

Related

Remove All Occurrences of a Given Value from a Doubly Linked List

Alright, so cut a long story short, what I'm trying to do here is remove all instances of value e from a doubly linked list. As far as I know, my logic is at least mostly right, but for some off reason it isn't actually removing any of the nodes in my test cases.
public boolean removeAll(int e) {
DIntNode dummy = head,next = null;
if (head == null)
return false;
while (dummy != null) {
if (dummy.getData() == e) {
next = dummy.getNext();
dummy.getNext().setPrev(null);
dummy = next;
return true;
}
else
dummy = dummy.getNext();
}
return false;
}
This is what I currently have for my code of the metho. My logic here was to use a dummy DIntNode that starts at the head and a "next" node to help me shrink the list, so to speak. In other words, if the list was something like "1<-> 1 <-> 2 <-> 3", the function would change it to "2<->3", in theory. The reason this is a boolean function is because I'm required to return true if the given value is removed form the list.
Is there just another step in the logic that I'm missing, or is the methodology itself just unreliable? I'm very unsure at this point, so any and all help would be greatly appreciated.
You set
dummy.getNext().setPrev(null);
But previous node also have reference to next node you try to remove. You should set this reference to next active value.
That because when you want to get all linked list previous value still know about node you remove, because of next node reference
You can try with the following code:
if (dummy.getData() == e) {
DIntNode temp = dummy.getPrevious();
temp.next = dummy.getNext();
temp = dummy.getNext();
temp.previous = dummy.getPrevious();
return true;
}
This used the previous reference. So the previous node will now have reference to the next node of your dummy node (node to be deleted). And similarly, the next node of dummy node will have reference of previous node of your dummy node. So, the dummy node will loose its connection/link from its doubly link list and that's what we want!
Please try.
Two issues with the code:
When relinking a doubly linked list, where removing B from A - B - C, you need to set the next node for A to be C as well as the previous node for C to be A. With trying to keep you method names:
A.setNext(current.getNext());
C.setNext(current.getPrev());
With your code, if you find an occurrence, you return, which means that no other instances will be removed since you jump out of that method. You will probably need a new boolean removed variable, that is set to false, return true changed to removed = true and return false changed to return removed.
The method exits after the first encounter of 'e'.
If you want to remove all instances of 'e', then you should have something like this:
boolean listChanged = false;
while (dummy != null) {
if (dummy.getData() == e) {
// update list
...
listChanged = true;
}
...
}
return listChanged;
Also, you should not write your code like this:
dummy.getNext().setPrev(...); // throws NPE if next is null

Unable to set reference variable in recursive call

I am using a recursive method to find a node in a binary tree using a key. When I find the node, I set it to my reference variable foundNode and return. The problem is that when I read the object its value is still null. Can anybody help?
findGivenNode(root, key, foundNode, parentStack);
private boolean findGivenNode(Node node, int key, Node foundNode, Stack<Node> parentStack) {
if (node == null) {
return false;
}
parentStack.add(node);
if (node.getData() == key) {
foundNode = node;
return true;
}
boolean leftReturn = findGivenNode(node.getLeftChild(), key, foundNode, parentStack);
boolean RightReturn = findGivenNode(node.getRightChild(), key, foundNode, parentStack);
if (leftReturn || RightReturn) {
return true;
} else {
parentStack.pop();
return false;
}
}
Java doesn't pass arguments by reference, they are passed by value. Read more here
Let's clarify by an example. Make the key you are looking for be integer with value 21.
The situation at the beginning of the function is the following:
So now, when you say:
foundNode = node; // this doesn't reflect outside of the method
You are changing the value of foundNode locally inside the findGivenNode() method, it doesn't apply to outside this method. Basically, the local variable called foundNode references the node you want to change and then you make this local variable foundNode reference the new node by the statement above.
This change is reflected only inside the function. As soon as your function is finished, local variables don't exist anymore so neither does this local version of foundNode. Visual result:
The simple solution is to use a Wrapper function
To keep track of the reference, you can make a simple wrapper class that will store the reference you want:
private class NodeWrapper {
Node foundNode;
NodeWrapper() {
foundNode = null;
}
}
Then you can create a new NodeWrapper and pass that into your function instead of foundNode
NodeWrapper wrapper = new NodeWrapper();
findGivenNode(root, wrapper, key, parentStack);
Then inside your function instead of:
foundNode = node;
You say:
wrapper.foundNode = node;
This way you can maintain the reference throughout the recursion inside the NodeWrapper. Meaning:
NodeWrapper wrapper = new NodeWrapper();
findGivenNode(root, wrapper, key, parentStack);
// at this point, wrapper.foundNode will hold the reference to the node you need
// or null if the node wasn't found
On another note, above the method you have this function prototype:
findGivenNode(root, key, foundNode, parentStack);
Seems like someone is still used to C/C++ :)
This is unnecessary in Java, you can read this question thread for reasoning behind that or just Google it.

Trying to create a removeLastElement using recursion

I need to make a method that removes the last element of a LinkedList using recursion.
This is what I have so far but it doesn't seem to be removing the node...when i call list.size() it is still the same size with the same values. What am I doing wrong here?
This is for Java by the way
public void removeLastElement(Node curr){
if (curr == null)
return;
else{
if(curr.next == null)
curr = null;
else
removeLastElement(curr.next);
}
}
In a LinkedList to remove the last element you have to get the penultimate element and set
curr.next = null
You're in the right way to get the recurrent function to remove the last node. The problem is you're identifying the penultimate node with curr.next == null, if you got it, you nullify it, but that's your actual input! So, you must check if the actual node is the antepenultimate node on the list:
if (curr.next.next == null) {
curr.next = null; //Now you're modifying the data in your input.
}
With this change, there are more basic cases to check, but that's up to you, my friend.
Boolean deleteLast(Node n)
{
if(n.next == null)
return true;
if(deleteLast(n.next))
{
n.next = null;
return false;
}
return false;
}
Node deleteLast(Node n) {
if (n.next == null)
return null;
n.next = deleteLast(n.next);
return this;
}
The general idea is you ask the next node "hey, can you tell me where you are, and delete your last node?" The last node can then just say "I'm nowhere" and it'll all fall into place.
This is very similar to Aadi's answer, just using Nodes instead of booleans.

Help making a singly linked list in Java

This is for homework but please know that I have looked online for help (such as http://www.sethi.org/classes/class_stuff/cis435/others/notes-java/data/collections/lists/simple-linked-list.html) and my textbook but I am still having some issues.
Any help would be appreciated...
Right now I'm trying to just insert values in but nothing is working. Whether it's the first item, whether it's being added as the last one, or somewhere in between.
Node header = null; // First element of list.
Node back = null; // Last element of list.
public void insert(int i, double value){ //insert value before i-th element
Node e = new Node();
e.num = value;
Node curr = header;
for(int x=0;x<i;x++) {
if (i == 1) { //we want to insert as first thing
if (size == 0) { //its the FIRST time we add something
header.next = e;
e.next = back;
break;
} else if (size == 1){
e.next = header.next; //i.e. the second thing in the list
header.next = e;
break;
} else {
e.next = header.next.next; //i.e. the second thing in the list
header.next = e;
break;
}
}
else if (x == (i-1)) {
e.next = curr.next;
curr.next = e;
break;
}
curr = curr.next;
}
size = size+1;
}
Not really sure why it isn't working.
Thanks!
For some reason, people who are still learning to program make things far more complicated then they need to be. I did it when I was learning java, I still do it when I am just getting into a new language, and students that I have marked find new and amazing ways to do it. You have more going on in your insert then there needs to be, for example, a method that inserts a value at a specific index should not check if it's the first item to be inserted (not saying it shouldn't check bounds). Here is the pseudo code of what I would do.
insert(index, value)
if index>size
throw null pointer
traverse to index -1 //lets call this nodeI
create newnode and set value
set newnode.next to nodeI.next
set nodeI.next to newnode
increase size.
Couple of handy hints for you, you should have a function to get an element from the link list, something that returns a node? public node elementAt(int index) for example? use that to traverse the linked list. If you want to append to the Linked list, try this
append(value)
insert(size-1,value)
and if you want to insert at the beginning? same idea
insert(value)
insert(0,value)
In the line e.next = header.next.next what would happen if header.next points to a 'null'? Is it possible to get there?
What are the corner cases you have to deal with and have you taken them all into account?
Can you start with the simplest case first, adding either an element to the front or an element to the back? Then use those functions to implement the insert?
A few suggestions:
implement java.util.List
Think about generics
Read this.
Start with "insert at the end" before you think about "insert at i".
I have tried a simple program, which will be useful for you guys, I am also learning Java, please bear with me for any mistakes, but this program works fine.
I am posting a very simple singly linked list program in Java, which I tried out today.
I hope it will help all.
LinkList.java
class LinkList
{
public static void main(String args[])
{
Node node = new Node(1);
node.addAtLast(2);
node.addAtLast(3);
node.addAtLast(4);
node.addAtLast(5);
node.printList();
}
}
Node.java
class Node
{
private int data;
private Node link;
public Node(int mydata)
{
data = mydata;
link = null;
}
public void printList()
{
System.out.print("|"+data+"|"+"->");
if(link != null)
{
//recursive call
link.printList();
}
else
{
//marking end of list as NULL
System.out.print("|NULL|");
}
}
public void addAtLast(int mydata)
{
if(link == null)
{
link = new Node(mydata);
}
else
{
link.addAtLast(mydata);
}
}
}
OUTPUT :
The below is our output
|1|->|2|->|3|->|4|->|5|->|NULL|

How do I add an object to a binary tree based on the value of a member variable?

How can I get a specific value from an object?
I'm trying to get a value of an instance
for eg.
ListOfPpl newListOfPpl = new ListOfPpl(id, name, age);
Object item = newListOfPpl;
How can I get a value of name from an Object item??
Even if it is easy or does not interest you can anyone help me??
Edited: I was trying to build a binary tree contains the node of ListOfPpl, and need to sort it in the lexicographic. Here's my code for insertion on the node. Any clue??
public void insert(Object item){
Node current = root;
Node follow = null;
if(!isEmpty()){
root = new Node(item, null, null);
return;
}boolean left = false, right = false;
while(current != null){
follow = current;
left = false;
right = false;
//I need to compare and sort it
if(item.compareTo(current.getFighter()) < 0){
current = current.getLeft();
left = true;
}else {
current = current.getRight();
right = true;
}
}if(left)
follow.setLeft(new Node(item, null, null));
else
follow.setRight(new Node(item, null, null));
}
Since your item variable is declared to be of the most basic Java type Object, you can't extract anything related to your data from it directly. The variable newListOfPpl, on the other hand, which is a reference to the same object, is declared to be of type ListOfPpl, so you can invoke on it whatever getter methods that have been defined in it (possibly getId(), getName(), getAge()).
That all depends on what ListOfPpl 'has inside it'.
Does it have a method to access it's data? or public data members?
For example, if ListOfPpl had a .getname() method.
Without knowing more about ListOfPpl I don't think I can be off much more help sorry.
Hope this was useful to you, and goodluck!

Categories