Java - Delete Node From Linked List - java

Okay so this is just a simple program that will receive input from a user and add it to a linked list, and also give them the options to view the list and delete a node. It compiles fine and can add nodes and display the list but it will not delete a node. It works when I hand code it without the keyboard input, even with the same variable name so that's where the problem is.
public class LinkedList {
public class Link {
public String content;
public Link next;
public Link(String content) {
this.content = content;
}
public void display(){
System.out.println(content);
}
}
public static Link head;
LinkedList(){
head = null;
}
public boolean isEmpty() {
return(head == null);
}
public void insertFirstLink(String content) {
Link newLink = new Link(content);
newLink.next = head;
head = newLink;
}
public void display() {
Link theLink = head;
while(theLink != null) {
theLink.display();
theLink = theLink.next;
}
}
public Link removeLink(String content) {
Link curr = head;
Link prev = head;
while(curr.content != content) {
if (curr.next == null) {
return null;
}
else {
prev = curr;
curr = curr.next;
}
}
if(curr == head) {
head = head.next;
}
else {
prev.next = curr.next;
}
return curr;
}
}
public class Testlist {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int choice = 0;
String content;
System.out.println("Enter 1 to add to list");
System.out.println("Enter 2 to display list");
System.out.println("Enter 3 to delete node");
System.out.println("Enter 4 to quit");
choice = keyboard.nextInt();
LinkedList newlist = new LinkedList();
while(choice != 4) {
if (choice == 1) {
content = keyboard.next();
newlist.insertFirstLink(content);
newlist.display();
}
if (choice == 2) {
newlist.display();
}
if (choice == 3) {
content = keyboard.next(); // this is where is goes wrong
newlist.removeLink(content);
newlist.display();
}
System.out.println("Enter 1 to add to list");
System.out.println("Enter 2 to display list");
System.out.println("Enter 3 to delete node");
System.out.println("Enter 4 to quit");
choice = keyboard.nextInt();
}
}
}

You're using !=, which compares by reference for objects, not by value. You want to use .equals(), ie:
while(!curr.content.equals(content))

Some one may have to double check, but i'm fairly sure this is because the nextInt() method grabs the first integer and thats all. which leaves the 'enter/carriage return' in the input stream. so when the next() method is run it grabs that enter. Definatly put in some debug lines to see what content is.

For comparing string you should use equals or equalsignorecase()
For example String1="xyz";
and String2="xyz" these two strings are different if you comare them using == or != as the objects are compared instead of the actual content . the correct implementation for your program would be
package stackoverflow.practice;
public class LinkedList {
public class Link {
public String content;
public Link next;
public Link(String content) {
this.content = content;
}
public void display(){
System.out.println(content);
}
}
public static Link head;
LinkedList(){
head = null;
}
public boolean isEmpty() {
return(head == null);
}
public void insertFirstLink(String content) {
Link newLink = new Link(content);
newLink.next = head;
head = newLink;
}
public void display() {
Link theLink = head;
while(theLink != null) {
theLink.display();
theLink = theLink.next;
}
}
public Link removeLink(String content) {
Link curr = head;
Link prev = head;
while(!curr.content.equalsIgnoreCase(content)) {
if (curr.next == null) {
return null;
}
else {
prev = curr;
curr = curr.next;
}
}
if(curr == head) {
head = head.next;
}
else {
prev.next = curr.next;
}
return curr;
}
}

Also use 'equals' in this line: 'if(curr == head) {'.

Related

Removing all instances of an element from a custom LinkedList

Im trying to remove all people from the list who have the same course name in my custom LinkedList class. I have managed to get my programme to delete people individually based on number however can not figure out how to remove multiple at once. I have browsed online for any solutions and have tried multiple so far but none to any success I also attempted one myself but also no success any help or links to were I could learn mode would be greatly appreciated. Below is my Driver, LinkedList, and LinearNode class. I have also removed code I beleive is not relevant to this solution :).
Linked List Class
public class LinkedList<T> implements LinkedListADT<T> {
private int count; // the current number of elements in the list
private LinearNode<T> list; //pointer to the first element
private LinearNode<T> last; //pointer to the last element
//-----------------------------------------------------------------
// Creates an empty list.
//-----------------------------------------------------------------
public LinkedList()
{
this.count = 0;
this.last = null;
this.list = null;
}
public void add (T element)
{
LinearNode<T> node = new LinearNode<T> (element);
if (size() == 0) {
this.last = node; // This is the last and the
this.list = node; // first node
this.count++;
}//end if
else
{
last.setNext(node); // add node to the end of the list
last = node; // now make this the new last node.
this.count++;
} //end else
}
public T remove()
{
LinearNode<T> current = list;
LinearNode<T> temp = list;
T result = null;
if (current == null) {
System.out.println("There are no such employees in the list");
}//end if
else {
result = this.list.getElement();
temp = list;
this.list = this.list.getNext();
temp.setNext(null); //dereference the original first element
count--;
}//end else
return result;
}
public T remove(T element)
{
LinearNode<T> current = list;
LinearNode<T> previous = list;
LinearNode<T> temp;
T result = null;
if (current == null) {
System.out.println("There are no such employees in the list");
}//end if
else {
for (current = this.list; current != null && !current.getElement().equals(element); current = current.getNext())
{
previous = current;
}
if(current == null) {
System.out.println("No such employee on the list");
}
else if (current == list)
{
remove();
}
else if(current == last) {
previous.setNext(null);
this.last = previous.getNext();
count--;
}
else
{
previous.setNext(current.getNext());
count--;
}
}
return result;
}
**
My attempted Solution**
public T clear(T element) {
T result = null;
while (this.list != null && this.list.getElement() == element) {
this.list = this.list.getNext();
count--;
}
if (this.list == null) {
return result;
}
LinearNode<T> current = this.list;
while (current.getNext() != null) {
if (current.getNext().getElement() == element) {
current.setNext(current.getNext());
count--;
} else {
current = current.getNext();
}
}
return result;
}
}
LinearNode Class
public class LinearNode<T>
{
private LinearNode<T> next;
private T element;
//---------------------------------------------------------
// Creates an empty node.
//---------------------------------------------------------
public LinearNode()
{
this.next = null;
this.element = null;
}
//---------------------------------------------------------
// Creates a node storing the specified element.
//---------------------------------------------------------
public LinearNode (T elem)
{
this.next = null;
this.element = elem;
}
//---------------------------------------------------------
// Returns the node that follows this one.
//---------------------------------------------------------
public LinearNode<T> getNext()
{
return this.next;
}
//---------------------------------------------------------
// Sets the node that follows this one.
//---------------------------------------------------------
public void setNext (LinearNode<T> node)
{
this.next = node;
}
//---------------------------------------------------------
// Returns the element stored in this node.
//---------------------------------------------------------
public T getElement()
{
return this.element;
}
//---------------------------------------------------------
// Sets the element stored in this node.
//---------------------------------------------------------
public void setElement (T elem)
{
this.element = elem;
}
}
Driver Class
public class TrainingCourses {
LinkedList<employee>list;
int Size =10;
int numberofEmployees=0;
public TrainingCourses() {
list = new LinkedList<employee>();
inputEmployee();
displayEmployee();
deleteCourses();
displayEmployee();
}
public void inputEmployee() {
employee a;
a = null;
String number,name,courseName = null;
int years;
Scanner scan = new Scanner(System.in);
for (int count = 1; count<=numberofEmployees; count++){
System.out.println("Input employee number");
number = scan.nextLine();
System.out.println("Input employee name");
name = scan.nextLine();
System.out.println("Input years at organisation");
years = scan.nextInt(); scan.nextLine();
if(years >=5) {
System.out.println("Input course name");
courseName = scan.nextLine();
}else {
System.out.println("Can not join training course employee must be with organisation 5 or more years");
}
a = new employee(number,name,years,courseName);
list.add(a);
}
}
public void displayEmployee() {
System.out.println("\nDisplaying all employees....");
System.out.println(list.toString());
}
public void deleteCourses(){
{
Scanner scan = new Scanner(System.in);
employee b = null;
String number,name,courseName;
int years;
System.out.println("Enter employee number you wish to remove");
number = scan.nextLine();
System.out.println("Input employee name");
name = scan.nextLine();
System.out.println("Input years at organisation");
years = scan.nextInt(); scan.nextLine();
System.out.println("Input course name");
courseName = scan.nextLine();
b = new employee(number,name,years,courseName);
list.clear(b);
}
}
public static void main(String[]args) {
new TrainingCourses();
}
}
I don't understand exactly what you want, because of you wrote you want "to remove all people from the list who have the same course name", but your code never checks only property, your code checks equality everywhere.
This example clear function removes all elements equals to param and returns count of removed elements.
public long clear(T element) {
long result = 0L;
LinearNode<T> current = this.list;
LinearNode<T> previous = null;
while (current != null) {
if (current.getElement().equals(element)) {
if (previous != null) {
if (current.getNext() != null) {
previous.setNext(current.getNext());
} else {
this.last = previous;
}
} else if (current.getNext() != null) {
this.list = current.getNext();
} else {
this.list = this.last = null;
}
this.count--;
result++;
} else {
previous = current;
}
current = current.getNext();
}
return result;
}
And after all .equals(..) only true, if the compared Objects has an equals() method and checks its content equality, otherwise two Objects equals by == operator, if they are exactly the same (not by there's contents).

How do you delete a certain node based on a name inputted by the user

I want to delete a certain node in a linked-list but, I can't use java.util.LinkedList
The final result should be like this.
How do you find a node based on its name?
Can you find the nodes index based on its name, and delete it the original way?
L = (mon, wed, fri)
Please enter the desired data you want to delete. >> wed
L = (mon, fri)
Adding my original code, hope it will help.
package week4;
public class C {
public static void main(String args[]) {
LinkedList L = new LinkedList();
System.out.println("Add three nodes.");
L.insertLastNode("mon");
L.insertLastNode("wed");
L.insertLastNode("sun");
L.printList();
System.out.println("Add fri behind wed.");
ListNode pre = L.searchNode("wed");
if(pre == null)
System.out.println("Error >> No data found");
else {
L.insertMiddleNode(pre, "fri");
L.printList();
}
System.out.println("Delete last node.");
L.deleteLastNode();
L.printList();
System.out.println("Please enter the desired data you want to delete. >> ");
}
}
class LinkedList{
private ListNode head;
public LinkedList() {
head = null;
}
public void insertMiddleNode(ListNode pre, String data) {
ListNode newNode = new ListNode(data); //-> new |data|null|
newNode.link = pre.link; //-> new |data|pre.link|
pre.link = newNode; //-> pre |predata|new.link|
}
public void insertLastNode(String data) {
ListNode newNode = new ListNode(data); //-> new |data|null|
if(head == null) {
this.head = newNode;
}
else{
ListNode temp = head;
while(temp.link != null)
temp = temp.link;
temp.link = newNode;
}
}
public void deleteLastNode() {
ListNode pre, temp;
if(head == null)
return;
if(head.link == null) {
head = null;
}
else {
pre = head;
temp = head.link;
while(temp.link != null) {
pre = temp;
temp = temp.link;
}
pre.link = null;
}
}
public ListNode searchNode(String data) {
ListNode temp = this.head;
while(temp != null) {
if(data == temp.getData())
return temp;
else temp = temp.link;
}
return null;
}
public void reverseList() {
ListNode next = head;
ListNode current = null;
ListNode pre = null;
while(next != null) {
pre = current;
current = next;
next = next.link;
current.link = pre;
}
head = current;
}
public void printList() {
ListNode temp = this.head;
System.out.printf("L = (");
while(temp != null) {
System.out.printf(temp.getData());
temp = temp.link;
if(temp != null) {
System.out.printf(", ");
}
}
System.out.println(")");
}
}
class ListNode {
private String data;
public ListNode link;
public ListNode() {
this.data = null;
this.link = null;
}
public ListNode(String data) {
this.data = data;
this.link = null;
}
public ListNode(String data, ListNode link) {
this.data = data;
this.link = link;
}
public String getData() {
return this.data;
}
}
You'll have to have a method that identifies the node that precedes the node with the data to delete. You already have a searchNode, so it should be similar.
But searchNode has a problem: it does not compare strings in the right way. You should use the .equals method. Change this line:
if(data == temp.getData())
to:
if(temp.getData().equals(data))
Here is the method you would need to delete one (or more) nodes that have the given data:
public void deleteNode(String data) {
if (head == null)
return;
if (head.getData().equals(data)) {
head = head.link;
return;
}
ListNode temp = head;
while (temp.link != null) {
if (temp.link.getData().equals(data)) {
temp.link = temp.link.link;
} else {
temp = temp.link;
}
}
}
In the main program you would do this:
System.out.println("Please enter the desired data you want to delete. >> ");
Scanner scanner = new Scanner(System.in);
String data = scanner.nextLine();
L.deleteNode(data);
L.printList();

Complete Linked List will not Print all Value

I think I'm having trouble with my Queue class because I know using a Queue uses the FIFO method, but want to make sure that when I add an element that it is added at the end of the Queue. In my main program I have added numbers 1-4, but when I want to print my entire Queue using the toString method in my Queue class it will only print out the first element which is 1. I would appreciate some help!
Thank you!
public class QuestionFive
{
public static void main(String[] args)
{
// creating a queue
Queue q = new Queue();
// adding numbers 1,2,3 and 4
q.insert(1);
q.insert(2);
q.insert(3);
q.insert(4);
System.out.println(q);
}
}
class Queue
{
//Private Data Member
private Link _head;
//Constructor: A constructor to create an empty Queue,
public Queue()
{
_head = null;
}
//Insert Method: A method to insert a given Object into the Queue.
//Note: We will inserton
public void insert(Object item)
{
Link add = new Link();
add.data = item;
add.next = null;
if(_head == null)
{
_head = add;
}
else
{
for(Link curr = _head; curr.next != null; curr = curr.next)
{
curr.next = add;
}
}
}
//Delete Method: A method to delete an Object from the Queue
public Object delete()
{
if ( _head == null ) return null;
Link prev = null;
Link curr = _head;
while (curr.next != null )
{
prev = curr;
curr = curr.next;
}
if ( prev != null )
{
prev.next = null;
}
else
{
_head = null;
}
return curr.data;
}
// IsEmpty Method: A method to test for an empty Queue
public boolean isEmpty()
{
// queue is empty if front is null
return (_head == null);
}
//toString Method:
public String toString()
{
String s = "";
for (Link curr = _head; curr != null; curr = curr.next)
{
s = s + " " + curr.data;
}
return s;
}
}
//Link Class
class Link
{
public Object data;
public Link next;
}
A much simpler approach is to introduce a tail as well as a head making your queue double-ended, no need to iterate through the entire queue every time you add an item.
class Queue {
private Link head;
private Link tail;
public void insert(Object item) {
Link add = new Link();
add.data = item;
add.next = null;
if(head == null)
{
head = add;
tail = add;
}
else {
tail.next = add;
tail = add;
}
}
}
The method should really be called add since it is appending to the end not inserting.
The logic in your insert() method needs attention. I have modified the else part of the method as follows and it worked:
else
{
for(Link curr = _head; ; curr = curr.next)
{
if(curr.next == null){
curr.next = add;
break;
}
}
}
Here is the full working class:
public class QuestionFive
{
public static void main(String[] args)
{
// creating a queue
Queue q = new Queue();
// adding numbers 1,2,3 and 4
q.insert(1);
q.insert(2);
q.insert(3);
q.insert(4);
System.out.println(q);
}
}
class Queue
{
//Private Data Member
private Link _head;
//Constructor: A constructor to create an empty Queue,
public Queue()
{
_head = null;
}
//Insert Method: A method to insert a given Object into the Queue.
//Note: We will inserton
public void insert(Object item)
{
Link add = new Link();
add.data = item;
add.next = null;
if(_head == null)
{
_head = add;
}
else
{
for(Link curr = _head; ; curr = curr.next)
{
if(curr.next == null){
curr.next = add;
break;
}
}
}
}
//Delete Method: A method to delete an Object from the Queue
public Object delete()
{
if ( _head == null ) return null;
Link prev = null;
Link curr = _head;
while (curr.next != null )
{
prev = curr;
curr = curr.next;
}
if ( prev != null )
{
prev.next = null;
}
else
{
_head = null;
}
return curr.data;
}
// IsEmpty Method: A method to test for an empty Queue
public boolean isEmpty()
{
// queue is empty if front is null
return (_head == null);
}
//toString Method:
public String toString()
{
String s = "";
for (Link curr = _head; curr != null; curr = curr.next)
{
s = s + " " + curr.data;
}
return s;
}
}
//Link Class
class Link
{
public Object data;
public Link next;
}
Fixed in your Code(instead toString method printList):
public class QuestionFive
{
public static void main(String[] args)
{
// creating a queue
Queue q = new Queue();
// adding numbers 1,2,3 and 4
q.insert(1);
q.insert(2);
q.insert(3);
q.insert(4);
q.printList();
System.out.println(q);
}
}
class Queue
{
//Private Data Member
private Link _head;
//Constructor: A constructor to create an empty Queue,
public Queue()
{
_head = null;
}
//Insert Method: A method to insert a given Object into the Queue.
//Note: We will inserton
public void insert(Object item)
{
Link add = new Link();
add.data = item;
add.next = _head;
_head = add;
}
//Prints list data
public void printList() {
Link currentLink = _head;
System.out.print("List: ");
while(currentLink != null) {
currentLink.printLink();
currentLink = currentLink.next;
}
System.out.println("");
}
//Delete Method: A method to delete an Object from the Queue
public Object delete()
{
if ( _head == null ) return null;
Link prev = null;
Link curr = _head;
while (curr.next != null )
{
prev = curr;
curr = curr.next;
}
if ( prev != null )
{
prev.next = null;
}
else
{
_head = null;
}
return curr.data;
}
// IsEmpty Method: A method to test for an empty Queue
public boolean isEmpty()
{
// queue is empty if front is null
return (_head == null);
}
}
//Link Class
class Link
{
public Object data;
public Link next;
//Print Link data
public void printLink() {
System.out.print("{" + data + "}");
}
}

Unable to delete last node in linked list

I trying to delete the last node from my singly-linked list. But I am still unable to resolve this error in code. My deleteFromEnd method is not removing the last node. After calling the delete method, it's still showing the node that I want to delete. The rest of the list is deleted, but the last node itself is not removed. Can you tell me what I am missing, or where the error is?
LinkedList:
package lab5;
public class LinkedList {
public static void main(String argsp[]) {
List ob = new List();
ob.addAtStart("y", 6);
ob.addAtStart("w", 4);
ob.addAtStart("z", 3);
ob.addAtEnd("a", 3);
ob.addAtEnd("b", 4);
ob.addAtEnd("c", 5);
/*
* ob.display(); System.out.println("Deleted first one");
* ob.deleteFromStart();
*/
ob.display();
System.out.println("Deleted End one");
ob.deleteFromEnd();
ob.display();
}
}
List:
package lab5;
public class List {
Node head;
public List() {
head = null;
}
public List(Node e) {
head = e;
}
Node oldfirst = null;
Node lasthead = null;
public void addAtStart(String name, int age) {
Node newObject = new Node(name, age);
newObject.next = head;
if (oldfirst == null) {
oldfirst = newObject;
}
head = newObject;
lasthead = head;
}
public void display() {
Node store = head;
while (store != null) {
store.display();
store = store.next;
System.out.println();
}
}
public void addAtEnd(String name, int age) {
Node atEndValue = new Node(name, age);
oldfirst.next = atEndValue;
oldfirst = atEndValue;
}
public void deleteFromStart() {
if (head.next != null) {
head = head.next;
}
}
public void deleteFromEnd() {
Node start = head;
Node prev = null;
while (head != null) {
prev = head;
head = head.next;
}
prev.next = null;
head = prev;
}
public Node search(String name) {
return head;
}
public boolean isEmpty() {
return head == null;
}
public int size() {
return (head.toString()).length();
}
}
Node:
package lab5;
public class Node {
String name;
int age;
Node next;
public Node() {
name = "Abc";
age = 10;
next = null;
}
public Node(String name, int age) {
this.name = name;
this.age = age;
next = null;
}
public void display() {
System.out.println("Name: " + name + " Age: " + age);
}
}
You are modifying head pointer of list which is wrong. Following method worked for me.
public void deleteFromEnd() {
Node start = head;
Node prev = null;
if(start == null || start.next == null)
{
head = null;
return;
}
while (start.next != null) {
prev = start;
start = start.next;
}
prev.next = null;
}
After analysing your code for little more, I found few other issues. You would need to update addAtStart and addAtEnd methods.
Node lasthead = null;
public void addAtStart(String name, int age) {
Node newObject = new Node(name, age);
newObject.next = head;
if(head == null)
lasthead = newObject;
else if(head.next == null)
lasthead = head;
head = newObject;
}
public void addAtEnd(String name, int age) {
Node atEndValue = new Node(name, age);
lasthead.next = atEndValue;
lasthead = atEndValue;
}
The reason being, suppose if I delete a single node from the end of the list. I would not be able to add an element to the end of the list.
When you're deleting from the end of a singly-linked list you have to do things:
Traverse the list, and create a variable to refer to the second-to-last element of your list.
Set the node after the second-to-last node to be null
You should never change the value of head while traversing your linked list, because that effectively deletes the entire list. You have no way of finding your way back to the beginning since you've overwritten your head variable. Instead, iterate using a temporary variable which is initialized as head.
Finally, remember to consider the edge-cases where the list only has 1 element, or is already empty:
public void deleteFromEnd() {
Node current = head;
Node previous = null;
while (current != null && current.next != null) {
previous = current;
current = current.next;
}
if (current == head) {
head = null;
}
if (previous != null) {
previous.next = null;
}
}
Do not change head of Linked List, otherwise you will loose the list.
Try following modification of your function:
public void deleteFromEnd() {
Node start = head;
Node prev = null;
if(start == null){
return;
}
if (start.next == null){
head = null;
return;
}
while (start.next != null) {
prev = start;
start = start.next;
}
prev.next = null;
}

How to search and Delete in a Linked List

I'm having a bit trouble with a little java activity that deals with searching and deleting a Linked List.
Here are the problems:
add a menu to method main to handle adding to head, deleting from the head and displaying a linked listed.
Then add a menu selection for deleting a particular element in the list and deleting it (so prompt the user for a string to delete - and then find it in the linked list and delete that element from the list).
Here are the classes:
public class LLNode {
private String data;
private LLNode next;
public LLNode() {
this.data = null;
this.next = null;
}
public LLNode (String newData) {
this.data = (newData);
this.next = null;
}
public void updateNode (LLNode nextOne) {
this.next = nextOne;
}
public String toString () {
return this.data;
}
public LLNode getNext() {
return this.next;
}
}
public class LList {
private LLNode head;
public LList() {
head = null;
}
public void addAtHead (String newData) {
LLNode newNode = new LLNode (newData);
newNode.updateNode(head);
head = newNode;
}
public void display() {
LLNode temp = head;
while (temp != null) {
System.out.println (temp);
temp = temp.getNext();
}
}
public LLNode deleteAtHead ( ) {
LLNode removedOne = head;
head = head.getNext();
return removedOne;
}
}
public class LinkedListExample {
public static void main(String[] args) {
LList list = new LList();
list.addAtHead("Bob");
list.addAtHead("Tom");
System.out.println("The list is ");
list.display();
LLNode removedOne = list.deleteAtHead();
System.out.println("After delete, the list new is ");
list.display();
System.out.println("The one that was deleted is..." + removedOne);
}
}
For creating a menu I would recommend using a while loop. You want to use some sort of scanner that checks for valid input and checks for the input of the menu.
{
public void main(String[] args) {
string input;
Scanner n = new Scanner(System.in);
while (!(input.equals("exit")) {
System.out.println("menu item 1");
System.out.println("menu item 2");
System.out.println("etc");
input = n.nextLine();
switch (input) {
case "menu 1": //do whatever menu 1 is
case "menu 2": //do whatever menu 2 is
case "exit": //exit // save whatever
default: System.out.println("message not understood");
}
}
This is a contains method. This should give you a strong indication on how to find an element in the linkedlist and how to delete it. (I'll leave this to you, as this is relatively easy and you need to learn).
public boolean contains(String str) {
Node ref;
while (ref != null)
ref = ref.next;
if (ref.data == str) {
return true;
}
return false;
}

Categories

Resources