I have a project for computer science class and have everything done except for one method. The delete method. Basically I am making a linked list from user input and I need to be able to delete all nodes (which is done) and delete a single specified node. So I need to search through the list of nodes find the one to delete and delete it. Anything that can help is appreciated. If you have a solution please offer an explanation as I am trying to learn and just solve the problem.
I'm not going to give you the GUI because I don't think it is necessary but here is the node class.
public class MagazineList {
private MagazineNode list;
public MagazineList(){
list = null;
}
public void add(Magazine mag){
MagazineNode node = new MagazineNode(mag);
MagazineNode current;
if(list == null) {
list = node;
}
else {
current = list;
while(current.next != null)
current = current.next;
current.next = node;
}
}
public void insert(Magazine mag) {
MagazineNode node = new MagazineNode (mag);
// make the new first node point to the current root
node.next=list;
// update the root to the new first node
list=node;
}
public void deleteAll() {
if(list == null) {
}
else {
list = null;
}
}
public void delete(Magazine mag) {
//Delete Method Goes Here
}
public String toString(){
String result = " ";
MagazineNode current = list;
while (current != null){
result += current.magazine + "\n";
current = current.next;
}
return result;
}
private class MagazineNode {
public Magazine magazine;
public MagazineNode next;
public MagazineNode(Magazine mag){
magazine = mag;
next = null;
}
}
}
UPDATE
Here is the method I put together and it goes through the first part into the while loop and never recognizes the same item in the list. I used the exact same thing for the input and delete methods yet it will not recognize it. Any help is appreciated.
public void delete (Magazine mag) {
MagazineNode current = list;
MagazineNode before;
before = current;
if(current.equals(mag)){
before.next = current;
System.out.println("Hello");
}
while ((current = current.next)!= null){
before = current.next;
System.out.println("Hello Red");
if(current.equals(mag)){
current = before;
System.out.println("Hello Blue");
}
}
}
Without spoon feeding you the answer. deletion is a bit like removing one link of a chain - you cut out the link and join up the two (new) ends.
So, deleting "B" would mean changing
A --> B --> C --> D
to this
A --> C --> D
In pseudo code, the algorithm would be:
start the algorithm with the first node
check if it is the one you want to delete
if not, go to the next node and check again (go back to the previous step)
if so, make the next node of the previous node the next node of this node
remove the reference from this node to the next node
public void delete (Magazine mag) {
MagazineNode current = this.list;
MagazineNode before;
//if is the first element
if (current.equals(mag)) {
this.list = current.next;
return; //ending the method
}
before = current;
//while there are elements in the list
while ((current = current.next) != null) {
//if is the current element
if (current.equals(mag)) {
before.next = current.next;
return; //endind the method
}
before = current;
}
//it isnt in the list
}
the comments should explains whats happening
All you need to do is search through the list, keeping track of where you are. When the node you want to delete is in front of you, set the current node's "next" to the one after the one you want to delete:
for(Node current = list; current.next() != null; current = current.next()){
if(current.next().magazine().equals(toDelete)) current.setNext(current.next().next());
}
Something like that.
Hope that helps!
Related
So, I have created a class that generates a generic doubly linked list. The problem is that the tester file keeps saying that I have done something incorrectly. It looks like it starts having problems with the deleting nodes portion of the test.
This is the deletion portion of the tester.
(The original numbers are 0,1,2,3,4,5,6,7,8,9 and the end result should be 1,3,4,5,6,7,8)
public static boolean deleteTest(GenDoubleLinkedList<Integer> intList)
{
printDecorated("Removing Test\nRemoving first item, third item, and last item");
intList.resetCurrent();
intList.deleteCurrent();
intList.goToNext();
intList.deleteCurrent();
while(intList.moreToIterate())
{
intList.goToNext();
}
intList.deleteCurrent();
intList.print();
return valuesMatch(intList,TEST_VALS_2);
}
These are my deleteCurrent, moreToIterate, resetCurrent and goToNext methods.
public void deleteCurrent() {
if(current != null && prev != null) {
System.out.println("DELETING " + current.data);
current = current.nextLink;
prev.nextLink = current;
next.prevLink = current;
}
else if(current != null && prev == null) {
System.out.println("DELETING " + current.data);
head = head.nextLink;
current = current.nextLink;
}
}
public boolean moreToIterate() {
//System.out.println(current.nextLink != null);
if(current.nextLink != null)
return true;
return false;
}
public void resetCurrent() {
current = head;
prev = null;
next = current.nextLink;
}
public void goToNext() {
//System.out.println(current.data);
if(current != null) {
current = current.nextLink;
prev = current.prevLink;
next = current.nextLink;
}
}
(I have the System.out.println()'s to troubleshoot.)
Here is what the console is outputting.
From my system out it looks like it should be deleting the correct nodes but when the test runs it obviously did not delete the correct ones. I am at a standstill and cannot figure out the issue.
If I need to I can give the entire tester file along with any of my code. Any help is appreciated.
current = current.nextLink should be changed to current = prev in your delete routine and current = current.nextLink should be removed from your "delete head" portion of your delete routine.
Please next time paste your cade it code tags so we can copy paste it to refer to it and also the line numbers...
I have a linked list I'm given and I need to find the first value in the list via a getFirst method.I need to display an error message and quit the program if the value is null. The linked list is already given to me link so:
class MyLinkedList
{
private class Node // inner class
{
private Node link;
private int x;
}
//----------------------------------
private Node first = null; // initial value is null
//----------------------------------
public void addFirst(int d)
{
Node newNode = new Node(); // create new node
newNode.x = d; // init data field in new node
newNode.link = first; // new node points to first node
first = newNode; // first now points to new node
}
//----------------------------------
public void traverse()
{
Node p = first;
while (p != null) // do loop until p goes null
{
System.out.println(p.x); // display data
p = p.link; // move p to next node
}
}
}
//==============================================
class TestMyLinkedList
{
public static void main(String[] args)
{
MyLinkedList list = new MyLinkedList();
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);
System.out.println("Numbers on list");
list.traverse();
}
}
Here's what I tried out for the method:
public static Node getFirst(Node list)
{
if (list == null)
{
System.out.println("Error!");
System.exit(1);
}
return MyLinkedList.first;
}
I know this isn't exactly right, we just started this in my class so I'm having trouble understanding what's going on with it. Thank you!
I think you should look at https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html and get an idea for the behavior of a linked list initially. Once you have an idea on how it behaves, you can think about how to add functionality around it. Right now you just have a single method which you call more than you should. What also might help is to create an interface and document it so you know what each method should do.
You should check that first isn't null in order to do what you describe in the question. Also, it is kind of weird that the first node autoreferences itself because usually it is left in null until you add another node
notice that the first value is linked to the first Node with is null. Then you have to check two things
Node == null (you got this)
Node.next == null (you have to do this)
When Node.next == null. It means that Node is first value because it is linked to the initial Node with is null.
Then you have
public static Node getFirst(Node list)
{
// if the list is empty
if (list == null)
{
System.out.println("Error!");
System.exit(1);
} else if(list.link == null) {
// this is the first value!
return list;
} else {
// keep searching recursive with the next Node
return getFirst(list.link);
}
}
The class MyLinkedList in your question follows the pattern of a stack data structure(At the time when i am writing this answer). That is: ever time you add a new element, the new element replaces the previously added element as the first element.
I guess you want to get 1 as your first element, if you have added elements 1,2,3 in that order. Correct me if i am wrong.
In that case your linked list and it's retrieval should be like this:
(Note: i have avoided private vars , public getter , settter , etc; to make code easily readable. But readers should add them.)
class Node{ int x; Node next; }
class LinkedList
{ Node head,tail;
void add(int y)
{ Node node = new Node();
node.x=y;
if(head==null)
head = tail = node;
else
tail = tail.next = node;
}
int getFirst()
{ if(head!=null)
return head.x;
else
throw new java.util.NoSuchElementException("List is empty");
}
}
If you look at java.util.LinkedList, you will find methods that are conventionally used in linked lists. If this is not a homework question, then i suggest you do not reinvent the wheel. Just use the existing libraries.
If you have to use the stack data structure, and you cannot change it, then i suggest you have to change your getFirst() like this:
int getFirst()
{ if(tail!=null)
return tail.x;
else
throw new java.util.NoSuchElementException("List is empty");
}
If you not allowed to add Node tail in your code, then your getFirst() will look like this:
int getFirst()
{ if(head==null)
throw new java.util.NoSuchElementException("List is empty");
Node node = head;
while(node.next!=null)
node=node.next;
return node.x;
}
I asked my friends about this and they said you can never take the current to the previous node and when I asked why they didn't give me a clear reason can anyone help me?
//here is the signature of the method;
public void remove (){
Node<T> tmp = null;
tmp.next = head;
// I want to delete the current by the way!;
while (tmp.next != current)
tmp = tmp.next;
tmp.next = current.next;
//now am taking the current to the node before it so that it only becomes null if the linkedlist is empty;
current=tmp;
}
The basic idea is sound if you are looking to mutate an existing linked list and remove an element. Although there is a lack of curly braces after the while and a NullPointException that will occur at the first tmp.next.
Generally a remove method would be passed the data in the node to remove. It's unclear in your question what current is supposed to point to. Your code does not support removing the head of the list or empty lists (null head).
Here's a potential implementation:
public boolean remove(T value) {
if (head == null) {
return false;
} else if (head.value.equals(value)) {
head = head.next;
return true;
} else {
Node<T> current = head;
while (current.next != null) {
if (current.next.value.equals(value)) {
current.next = current.next.next;
return true;
}
current = current.next;
}
return false;
}
}
If the current variable is supposed to end up pointing to the node before the removed node then you have a problem: what happens if you are removing the head of the list?
public void insertAfter(String after, String newName, int newPunkte)
{
ListNode newNode = new ListNode(newName, newPunkte, null);
if(head == null)
{
System.out.println("'InsertAfter' is not possible.");
return;
}
else
{
current = head;
while(current != null)
{
if(current.getName().equals(after))
{
System.out.println(after+" was found. "+newName+" was created.");
//Here is my problem...
current.setNext(newNode);
return;
}
previous = current;
current = current.getNext();
}
System.out.println(after+" was not found.");
return;
}
}
Hey guys, Ive got a little problem with my code. When I insert a new Node after
a (if so) found Node, the following Nodes (after the new one) are disappearing..
I pretty sure that the problem is that i didnt set "previous" after inserting.
Im pretty inexperienced with implementing Linked Lists.
I hope you can help me:)
By the way for understanding my code: The parameter "newPunkte" means "newPoints".
You need to set the next node on newNode:
ListNode next = current.getNext();
current.setNext(newNode);
newNode.setNext(next);
I'm trying to create a method that will add a node to my linked list. The method takes an int (to specify where the new link should go) and String (because my linked list holds strings). I wrote some code that I thought would add a link at specific point in my list, however when I print my list after supposedly adding a new node, I see that the new node has not been added. I'm pretty surprised because I was careful about testing the behavior of my code as I was writing it, and the add method seems to do what I expect--but the newly printed list isn't reflecting the changes after adding a new link. Can anyone tell where I'm going wrong :/
ps: the names of the classes and methods are not up for debate, my teacher chose them and that's how they must stay.
thanks!
Test Linked List
class LinkedListTest
{
public static void main(String[] args)
{
LinkedList list = new LinkedList();
list.insertFirst("cat");
list.insertFirst("dog");
list.insertFirst("fish");
list.insertFirst("cow");
list.insertFirst("horse");
list.insertFirst("pig");
list.insertFirst("chicken");
list.add(3, "mouse");
list.print();
}
}
Linked List Class
public class LinkedList
{
private Link first;
public LinkedList()
{
first = null;
}
public void insertFirst(String word)
{
Link link = new Link(word);
link.next = first;
first = link;
System.out.print(first.item + " ");
}
public String deleteFirst()
{
Link temp = first;
first = first.next;
return temp.item;
}
public String get(int index)
{
Link current = first;
while (index > 0)
{
index--;
current = current.next;
}
return current.item;
}
public void add(int index , String someString)
{
Link current = first;
while (index>0)
{
index--;
current = current.next;
}
Link newLink = new Link(someString);
newLink.next = current;
current = newLink;
}
public void print()
{
System.out.println("-----------PRINTING LIST------------");
Link current = first;
while(!(current==null))
{
System.out.println(current.item);
current = current.next;
}
}
}
Link Class
public class Link
{
public String item;
public Link next;
public Link(String theItem)
{
item = theItem;
}
}
When inserting into a list like this. You are going to have to set TWO 'next' links. The next pointing to the item you are inserting, and the next on the item you are inserting, pointing to the item you are scooting over.
Hope this helps.
newLink.next = current;
current = newLink;
The above code in your add method of LinkedList class should be: -
newLink.next = current.next;
current.next = newLink
current = newLink;
I hope this might solve your problem. You need to set two next links to insert a node in the middle. One at the current node pointing the next node, and one at the prevoius node pointing to the current node.
Look at where you are adding newLink into the current list. Hint... you aren't. You update current, which is a local variable to point at newLink, but you never set newLink to be the next of anything that is actually in your current linked list.