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;
}
Related
I created my own Linked List using nodes, and I have few methods to do.
Methods in main:
//List<Person> females = peopleFromWarsaw.getWithFilter(p -> p.getName().endsWith("a"));
// Dont know how to implements this methods.
// ObjectContainer.removeIf(p -> p.getAge() > 50);
// peopleFromWarsaw.storeToFile("youngPeopleFromWarsaw.txt",
// p -> p.getAge() < 30, p -> p.getName() + ";" + p.getAge() + ";" + p.getCity());
At the begging i made a linked list and tried to print elements from list but doesnt work.
At first it looks like it doesn't have a method toString but class Person has toString. I guess the program takes the node but I want to print object.
Maybe u can see what is the problem with code, basically nodes and methods in Object Container are fine.
Secondly i have a problem with implementing methods in main (getWithFilter,removeIf and storeToFile)
No matter how I write method in ObjectContainer, always intelij tells me that cannot use lambda and underline p.getName (p -> p.getName().endsWith("a"));
In class Person i have getters and setters with fields name,age.
Maybe someone could explain how properly write this methods ?
public class ObjectContainer<T> {
private Node head;
private Node tail;
private final Predicate<T> predicate;
public ObjectContainer(Predicate<T> predicate) {
this.predicate = predicate;
}
static class Node {
private Object object;
private Node next;
Node(Object object) {
this.object = object;
}
}
public void add(T object) {
if (!predicate.test(object)) {
throw new IllegalArgumentException("Element can not be added");
}
Node newNode = new Node(object);
if (head == null) {
head = newNode;
tail = newNode;
} else {
tail.next = newNode;
tail = newNode;
}
}
public int size() {
int count = 0;
Node current = head;
while (current != null) {
count++;
current = current.next;
}
return count;
}
public void push(T new_data) {
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
public void insertAfter(Node prev_node, T new_data) {
if (prev_node == null) {
System.out.println("The given previous node cannot be null");
return;
}
Node new_node = new Node(new_data);
new_node.next = prev_node.next;
prev_node.next = new_node;
}
public void append(T new_data) {
Node new_node = new Node(new_data);
if (head == null) {
head = new Node(new_data);
return;
}
new_node.next = null;
Node last = head;
while (last.next != null)
last = last.next;
last.next = new_node;
return;
}
public void printList() {
Node tnode = head;
while (tnode != null) {
tnode = tnode.next;
System.out.println(tnode);
}
}
}
Probably you don't want to print the node, but the object contained within. Also, you want to print the first object, too. That is
public void printList() {
Node tnode = head;
while (tnode != null) {
System.out.println(tnode.object);
tnode = tnode.next;
}
}
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();
I'm trying to write a method to insert a node and remove a node at the back of a linked list. Here's the main class I'm writing the methods in. They're at the bottom (insertBack and removeBack):
public class LinkedList
{
private LinkedListNode head;
public LinkedList()
{
head = null;
}
public LinkedListNode getHead()
{
return head;
}
public void setHead(LinkedListNode h)
{
head = h;
}
public void insertFront(Object item)
{
if (head == null)
{
LinkedListNode nextNode = new LinkedListNode (item);
head = nextNode;
}
else
{
LinkedListNode nextNode = new LinkedListNode (item);
nextNode.setNext(head);
head = nextNode;
}
}
public Object removeFront()
{
if (head == null)
{
return head;
}
else
{
LinkedListNode t = head;
Object ret = head.getData();
head = head.getNext();
t.setNext(null);
t = null;
return ret;
}
}
//insert a front at the end of linked list
public void insertBack(Object myData)
{
LinkedListNode newNode = new LinkedListNode(myData);
if (head == null)
{
head = newNode;
}
else
{
LinkedListNode current = head;
while (current.getNext() != null)
{
current = current.getNext();
}
current.setNext(newNode);
}
}
//remove a node at the end of linked list
public Object removeBack()
{
if (head == null)
{
return null;
}
if (head.getNext() == null)
{
return null;
}
LinkedListNode secondToLast = head;
while (secondToLast.getNext().getNext() != null)
{
secondToLast = secondToLast.getNext();
}
secondToLast.setNext(null);
return head.getData();
}
}
There's probably formatting errors as I pasted this here, but I'm still trying to figure out how to use this site. When I run my driver class, shown below, I get the results shown below that.
public static void main(String[] args)
{
ValueData data1 = new ValueData("a", 50);
ValueData data2 = new ValueData("b", 70);
ValueData data3 = new ValueData("c", 100);
LinkedList myList = new LinkedList();
//practice insertBack and removeBack
myList.insertBack(data1);
myList.insertBack(data2);
myList.insertBack(data3);
System.out.println("Test insertBack and removeBack");
System.out.println((ValueData) myList.removeBack());
System.out.println((ValueData) myList.removeBack());
System.out.println((ValueData) myList.removeBack());
System.out.println();
//compare insertFront and removeFront
System.out.println("Test insertFront and removeFront");
myList.insertFront(data1);
myList.insertFront(data2);
myList.insertFront(data3);
System.out.println((ValueData)myList.removeFront());
System.out.println((ValueData)myList.removeFront());
System.out.println((ValueData)myList.removeFront());
System.out.println();
RESULTS
Test insertBack and removeBack
a 50.0
a 50.0
null
Test insertFront and removeFront
c 100.0
b 70.0
a 50.0
Can anyone help me figure out why my removeFront and removeBack methods are not working?
First of all this code is unnecessary, as an object that has no reference will just be thrown away.
t.setNext(null);
t = null;
This also may help removeBack()
if(head == null) {
return null;
}
LindedListNode current = head;
while(current.getNext() != null) //searching for last node
current = current.getNext();
current = null; //make the last node null
I have been debugging this for hours and I cannot see any reason why my search method cannot find anything. and my toString only ever returns the first node, then again, nothing. can someone help me?
While debugging, I can confirm that the order of the list is correct, I can switch around the addLast and addFirst and will always return what should be the first element, but otherwise, I do not know. the first is always sored in head.info and during debugging I see that but then the prev and next are still null.
thanks in advance!
public class DoubleLinkedList {
private DoubleNode head;
public DoubleLinkedList() {
head = null;
}
public class DoubleNode {
int info;
DoubleNode prev;
DoubleNode next;
public DoubleNode(int key) {
info = key;
prev = next = null;
}
}
public DoubleNode search(int key) {
DoubleNode current = this.head;
while (current != null && current.info != key) {
current = current.next;
}
return current;
}
public void addFirst(int key) {
this.head = new DoubleNode(key);
}
public void addLast(int key) {
DoubleNode node = new DoubleNode(key);
DoubleNode current;
if (head == null) {
this.head = node;
} else {
current = this.head;
while (current.next != null) {
current = current.next;
current.next = node;
node.prev = current;
}
}
}
public int delete(int key) {
DoubleNode current, sent;
current = search( key );
if (current != null) {
sent = delete( current );
return sent.info;
} else {
return -1;
}
}
private DoubleNode delete(DoubleNode node) {
if (node.prev != null) {
(node.prev).next = node.next;
} else {
this.head = node.next;
}
if (node.next != null) {
(node.next).prev = node.prev;
}
return node;
}
public String toString() {
String string = "";
while (head != null) {
string += head.info + " ";
head = head.next;
}
return string;
}
public static void main(String[] args) {
DoubleLinkedList test = new DoubleLinkedList();
test.addLast( 3 );
test.addLast( 5 );
test.addFirst( 7 );
System.out.println(test);
System.out.println( "Search: " + test.search( 1 ) );
}
}
The results come out as:
7,
Search: null
Your addFirst method isn't currently setting the new head's next property. It needs to be something more like this:
public void addFirst(int key) {
DoubleNode node = new DoubleNode(key);
node.next = this.head;
this.head = node;
}
Take a look at this example:
public class Test {
public static void main(String[] args) {
List list = new List();
list.addNode("1");
list.addNode("2");
list.addNode("3");
System.out.println(list);// not implemented
}
}
class List {
Node head;
Node tail;
class Node {
Node next;
Node previous;
String info;
public Node(String info) {
this.info = info;
}
}
void addNode(String info) {
Node node = new Node(info);
if (head == null) {
head = tail = node;
} else if(tail == head){
Node next = new Node(info);
tail.next = next;
head = next;
head.previous = tail;
} else{
Node next = new Node(info);
Node current = head;
head.next =next;
head = next;
head.previous = current;
}
}
}
I'm trying to write a method called copyAlternate which copy alternate elements from a single linked list and put them in another Single linked list sent as a parameter in the method
for example: if the first Single Linked List is( 4,6,10,12,2)
the method should generate a single linked list with (4,10,2)
here is my code:
public boolean copyAlternate(SingleLinkedList<E> list1)
{
if(head==null)
return false;
Node <E> temp = head;
ArrayList <E> a1 = new ArrayList<E>();
while(temp!=null) {
a1.add(temp.data);
temp=temp.next;
}
Node<E> tmp1=list1.head;
for(int i=0;i<a1.size();i=i+2){
if(list1.head==null) {
list1.head =new Node(a1.get(i));
tmp1=head;
size++;
}
else
{
tmp1.next=new Node(a1.get(i));
size++;
tmp1=tmp1.next;
}
}
return true;
}
I got only 4 from method not (4,10,2)
so what is the problem with my code?
Here is a full example if you need it, try not to copy it entirely but study it and understand what it's doing:
public class Main {
public static void main(String[] args) {
SingleLinkedList<Integer> list = new SingleLinkedList<>();
// (4, 6, 10, 12, 2)
list.add(4).add(6).add(10).add(12).add(2);
SingleLinkedList<Integer> newList = copyAlternate(list);
System.out.println(newList);
// prints: (14, 10, 2)
}
public static class Node<T> {
public Node<T> next;
public T data;
public Node() {}
public Node(T data) {this.data = data;}
}
public static class SingleLinkedList<T> {
private Node<T> head;
private Node<T> tail;
public SingleLinkedList<T> add(T data) {
if (tail != null) {
tail.next = new Node<>(data);
tail = tail.next;
} else {
head = new Node<>(data);
tail = head;
}
return this;
}
#Override public String toString() {
StringBuilder sb = new StringBuilder();
if (head != null) {
sb.append(head.data);
Node<T> curr = head.next;
while (curr != null) {
sb.append(", ").append(curr.data);
curr = curr.next;
}
}
return sb.toString();
}
}
/**
* Copies only the even index nodes (0, 2, 4..) into a new list and returns that list.
* Doesn't create a deep copy of data
*/
public static <T> SingleLinkedList<T> copyAlternate(SingleLinkedList<T> list) {
Objects.requireNonNull(list, "list");
SingleLinkedList<T> newList = new SingleLinkedList<>();
Node<T> other = list.head;
if (other != null) {
// copy other data to head of new list and remember that as the current node
Node<T> curr = newList.head = new Node<>(other.data);
// get the next next other node
other = other.next;
if (other != null) {
other = other.next;
}
while (other != null) {
// copy the data into the next node then remember that as the current node
curr = curr.next = new Node<>(other.data);
// get the next next other node
other = other.next;
if (other != null) {
other = other.next;
}
}
}
return newList;
}
}
Another way you can achieve it. Hope it will help.
// define the structure of a single node
class ListNode<T>
{
public T data;
public ListNode<T> next;
public ListNode(T data)
{
this.data = data;
this.next = null;
}
}
public class SingleLinkedListGenerics<T>
{
private ListNode<T> head = null;
private ListNode<T> tail = null;
// used to insert a node at the end of linked list
public void insertLast(T data)
{
ListNode<T> newNode = new ListNode<>(data);
if (head == null)
{
head = tail = newNode;
}
else
{
tail.next = newNode;
tail = newNode;
}
}
// For printing Linked List
public void displayList()
{
System.out.println("\nPrinting LinkedList (head --> last) ");
ListNode<T> current = head;
while (current != null)
{
System.out.println(current.data + ", ");
current = current.next;
}
}
public static <T> SingleLinkedListGenerics<T> copyAlternate(SingleLinkedListGenerics<T> list)
{
if (list.head == null)
return null;
SingleLinkedListGenerics<T> newList = new SingleLinkedListGenerics<>();
ListNode<T> tmp = list.head;
ListNode<T> newNode = new ListNode<>(tmp.data); // getting the first node
newList.head = newNode;
newList.tail = newNode;
tmp = tmp.next;
while (tmp != null && tmp.next != null) //
{
tmp = tmp.next; // skipping one node
newList.insertLast(tmp.data);
tmp = tmp.next;
}
return newList;
}
public static void main(String args[])
{
SingleLinkedListGenerics<Integer> myLinkedlist = new SingleLinkedListGenerics<>();
myLinkedlist.insertLast(4);
myLinkedlist.insertLast(6);
myLinkedlist.insertLast(10);
myLinkedlist.insertLast(12);
myLinkedlist.insertLast(2);
myLinkedlist.displayList();
SingleLinkedListGenerics<Integer> myLinkedlist1 = copyAlternate(myLinkedlist);
myLinkedlist1.displayList();
}
}