Remove all nodes with a given value using Java - java

I need to remove all nodes with a given value. However, my code removes them, but the final result I get is if the value is at the head, it doesn't delete. How can I fix this problem?
public LinkedListNode remove(LinkedListNode head, int value)
{
if( head == null)
return head;
LinkedListNode current = head;
LinkedListNode trailcurrent = null;
while(current != null)
{
if(current.value == value)
{
if(current == head)
{
head = head.next;
current = head;
}
else{
trailcurrent.next = current.next;
current = trailcurrent.next;
}
}
else
{
trailcurrent = current;
current = current.next;
}
}
return head;
}

The code that you show is correct. I've added a little bit to get a complete example:
public class LinkedListNode {
public LinkedListNode next;
public int value;
}
and
public class LinkedListTest {
public static LinkedListNode remove(LinkedListNode head, int value) {
if (head == null) {
return head;
}
LinkedListNode current = head;
LinkedListNode trailcurrent = null;
while (current != null) {
if (current.value == value) {
if (current == head) {
head = head.next;
current = head;
} else {
trailcurrent.next = current.next;
current = trailcurrent.next;
}
} else {
trailcurrent = current;
current = current.next;
}
}
return head;
}
public static LinkedListNode createLinkedList(int... values) {
LinkedListNode result = null;
for (int i = values.length - 1; i >= 0; i--) {
LinkedListNode n = new LinkedListNode();
n.value = values[i];
n.next = result;
result = n;
}
return result;
}
public static void printList(LinkedListNode head) {
while (head != null) {
System.out.print(head.value+" ");
head = head.next;
}
System.out.println();
}
public static void main(String... args) {
LinkedListNode head = createLinkedList(3,5,3,2);
printList(head);
head = remove(head, 3);
printList(head);
printList(remove(head, 5));
}
}
and it prints
3 5 3 2
5 2
2
So the problem must be somewhere outside of the code that you show.

I have tried to run the code on my system, but by making some changes. The program just runs fine :) But I found an insight which I think you will find interesting. Anyway the code goes like this below:
ListNode.java
public class ListNode<T>{
public T data;
public ListNode<T> next;
public int nos;
}
LinkedListPer.java
public class LinkedListPer {
//ListNode<Integer> list = new ListNode<Integer>();
ListNode<Integer> add(ListNode<Integer> head, int x){
ListNode<Integer> p = head;
if(head==null){
head = new ListNode<Integer>();
head.data = x;
}else{
while(p.next!=null){
p=p.next;
}
p.next = new ListNode<Integer>();
p.next.data = x;
}
return head;
}
void display(ListNode<Integer> head){
ListNode<Integer> p = head;
while(p.next!=null){
System.out.print(p.data+"->");
p = p.next;
}
System.out.println("NULL");
}
ListNode<Integer> delete(ListNode<Integer> head, int val){
if(head==null){
return head;
}
ListNode<Integer> prev = head;
ListNode<Integer> curr = head;
while(curr.next!=null){
if(curr.data == val){
if(curr==head){
head = curr.next;
curr = head;
}else{
prev.next = curr.next;
curr = prev.next;
}
}else{
prev = curr;
curr = curr.next;
}
}
return head;
}
}
In ran the following codes in main.
LinkedListPer dh = new LinkedListPer();
ListNode<Integer> ln = null;
ln = dh.add(ln, 1);
ln = dh.add(ln,2);
ln = dh.add(ln,1);
ln = dh.add(ln,4);
ln = dh.add(ln,6);
dh.display(ln);
ln = dh.delete(ln, 1);
dh.display(ln);
I got the following output:
1->2->1->4->NULL
2->4->NULL
Now for the Insight:
Earlier on performing the delete() operation, I didn't save the value returned by the same. i.e. I only wrote the following statement.
dh.delete(ln,1)
The output was as follows:
1->2->1->4->NULL
1->2->4->NULL
So, I suppose this exactly fits the behavior of the problem that you face. I think the problem lies in using the head after performing the delete operation(s).

Related

JAVA- Printing out LinkedLists in an ArrayList [duplicate]

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 1 year ago.
I am trying to print out the elements in my ArrayList that looks like
static ArrayList<LinkedList> listy = new ArrayList<>();
I tried to create a function called PrintTest()
public static void pTest() {
String [] top;
for (LinkedList i: listy) {
//i.show();
System.out.println(i.toString());
However, I am still getting when I call printTest()
LinkedList#15975490
LinkedList#6b143ee9
LinkedList#1936f0f5
LinkedList#6615435c
LinkedList#4909b8da
LinkedList#3a03464
LinkedList#2d3fcdbd
LinkedList#617c74e5
Do I need to iterator over this once more? I am confused on how to go about this. Can I override toString()? I can't seem to get it to work
Here is my linkedlist implementation code
public class LinkedList {
Node head;
Node tail;
public String getFirst() {
Node node = head;
if (node.next == null) {
throw new NoSuchElementException();
}
else {
return node.data;
}
}
public void insert(String data) {
Node node = new Node();
node.data = data;
node.next = null;
if (head == null) {
head = node;
}
else {
Node n = head;
while(n.next !=null) {
n = n.next;
}
n.next = node;
}
}
public void insertAtStart(String data) {
Node node = new Node();
node.data = data;
node.next = null;
node.next = head;
head = node;
}
public void insertAt(int index, String data) {
Node node = new Node();
node.data = data;
node.next = null;
if(index == 0) {
insertAtStart(data);
}
else {
Node n = head;
for (int i = 0; i < index-1; i++) {
n = n.next;
}
node.next = n.next;
n.next = node;
}
}
public void deleteAt(int index) {
if (index == 0) {
head = head.next;
}
else {
Node n = head;
Node n1 = null;
for (int i = 0; i < index-1; i++) {
n = n.next;
}
n1 = n.next;
n.next = n1.next;
//System.out.println("n1 " + n1.data);
n1 = null;
}
}
public int size() {
int count =0;
Node pos = head;
while (pos != null) {
count++;
pos = pos.next;
}
return count;
}
public void remove(String s) {
Node node = head;
while (!node.data.equals(s)) {
node = node.next;
}
if (node.next == null) {
node.data = null;
}
else {
node.data = node.next.data;
node.next = node.next.next;
}
//System.out.println("n1 " + n1.data);
}
public void show() {
Node node = head;
while(node.next != null) {
System.out.println(node.data);
node = node.next;
}
System.out.println(node.data);
In java, every class inherits the Object class. In the Object class default definition for the toString method is hashcode. When you are calling toString method, you need to define by yourself.
class LinkedList{
int value;
#Override
public String toString(){
return String.valueOf(value);
}
}
I think you can go through this article to get more understanding.Explanation For toString

Error while removing two nodes in doubly linked list in java

I have problems in doubly LinkedList and I am not using a tail I instead use a current pointer. When I use the tail I don't find problem but when I use a current pointer I get an error and I can not solve it. It occurs when I remove a node. My program is working but I can not remove the next node.
This is the error message:
This the class DNode
public class DNode<T> {
T data;
DNode<T> next;
DNode<T> prev;
public DNode(T e){
data = e;
next = prev = null;
}
This class DoubleLinkedList
public class DoubleLinkedList<T> {
DNode<T> head;
DNode<T> current;
int size = 0;
public DoubleLinkedList() {
head = current = null;
}
public void Insert(T e) {
DNode<T> tmp = new DNode(e);
if (size == 0) {
head = current = tmp;
} else {
tmp.next = current.next;
tmp.prev = current;
current.next = tmp;
current = tmp;
}
size++;
}
public void remove() {
if (head == current) {
if (current.next == null) {
head = current = null;
} else {
current.next.prev = null;
head = current.next;
current.next = null;
current = head;
}
} else {
DNode<T> tmp = current.next;
current.prev.next = tmp;
if (tmp != null) {
tmp.prev = current;
}
current.next = current.prev = null;
current = tmp;
}
size--;
}
The main calss
public static void main(String[] args) {
DoubleLinkedList<String> d = new DoubleLinkedList();
d.Insert("jon");
d.Insert("jack");
d.Insert("mohammed");
d.remove();
d.remove();// here my problem
}
The line with the comment is where I get an error.
In the else part of your remove function, you assign current to tmp. When you say current = tmp; tmp could be null. So the next time when the remove is called, if it enters the else clause(which it would in your case) current will be null, and current.next gives the null pointer exception.
EDIT :
This would be a possible suggestion :
/*Deletes the last node in the list*/
public void remove() {
if(head == null || size == 0) return; // Empty list
if(head == current || size ==1){ // List with only one node
head = null;
current = null;
size--;
return;
}
DNode<T> previous = current.prev;
previous.next = current.next;
current.prev = null;
current = previous;
size--;
}

Generic Doubly Linked List Implementation

So I have this basic generic implantation of generic doubly linked list. I have created an insert method which is going to add a node according to the order.
public class DoublyLL <T extends Comparable<T>> {
DNode<T> head;
DNode<T> tail;
public void insertInOrder(T item) { //To create an "ordered" linked list
DNode <T> n = new DNode<>();
if (head == null) {
head = n;
n.data = item;
}
else {
DNode<T> temp = head;
while (temp != null && n.data.compareTo(temp.data) > 0) { // line 18
temp = temp.next;
}
if (temp == head) { //inserting node in first
head.prev = n;
n.next = head;
head = n;
n.data = item;
}
else if (temp == null) { // inserting at last
tail.next = n;
n.prev = tail;
tail = n;
n.data = item;
}
else { //inserting in middle
n.prev = temp.prev;
n.next = temp;
temp.prev.next = n;
temp.prev = n;
n.data = item;
}
}
}
#Override
public String toString() {
DNode temp = head;
String str = "";
while (temp != null) {
str += temp.data + " ";
temp = temp.next;
}
return str;
}
public static void main(String[] args) {
DoublyLL<Integer> list = new DoublyLL<>();
list.insertInOrder(2);
list.insertInOrder(222); //line 62
list.insertInOrder(22222);
System.out.println(list);
}
}
class DNode<T> {
T data;
DNode prev;
DNode next;
}
However, when I'm running this I'm getting the NullPointerException at line 18 and 62. What can I do to get rid of that to make the ordered list like, "2, 22, 2222?
It's hard to say what's the problem without stack trace but it looks like instead of
if (head == null) {
head = n;
n.data = item;
}
you should have
if (head == null) {
head = n;
tail = n;
n.data = item;
}
Otherwise your tail remains null.

LinkedList Insert Last

I am trying to insert element at the end of a linked list insertAtEnd(). When I debug the code I see a node(0,null) is being inserted as default in the beginning of the insertion. I think this is causing the problem while iterating through the list. Any suggestions on how fix this?
package com.ds.azim;
public class Node {
//Node has 1. Data Element 2. Next pointer
public int data;
public Node next;
//empty constructor
public Node(){
//
}
public Node(int data){
this.data= data;
this.next = null;
}
public Node(int data, Node next){
this.data = data;
this.next = next;
}
}
//*************************************//
package com.ds.azim;
public class SingleLinkedList {
//Single Linked list has a head tail and has a length
public Node head;
public Node tail;
public int length;
//constructor
public SingleLinkedList(){
head = new Node();
length = 0;
}
public void insertAtFirst(int data){
head = new Node(data,head);
}
public void insertAtEnd(int data){
Node curr = head;
if(curr==null){
insertAtFirst(data);
}else{
while(curr.next!=null){
curr = curr.next;
}
curr.next = new Node(data,null);
}
}
public void show(){
Node curr = head;
while(curr.next!=null){
//do something
System.out.print(curr.data+",");
curr = curr.next;
}
}
public static void main(String[] args){
SingleLinkedList sll = new SingleLinkedList();
sll.insertAtFirst(12);
sll.insertAtFirst(123);
sll.insertAtFirst(890);
sll.insertAtEnd(234);
sll.show();
}
}
Along with removing this part of the code
public SingleLinkedList() {
head = new Node();
length = 0;
}
change your show function as well, because this will not print the last element
while(curr.next!=null){
//do something
System.out.print(curr.data+",");
curr = curr.next;
}
after this while, put one more print statement to print the last element.
System.out.print(curr.data);
this will fix the errors.
Your code initializes the list with a Node containing (0, null) and head pointing to it. To fix this, don't do that.
public SingleLinkedList() {
head = new Node();
length = 0;
}
Also in that code you set length = 0;, but actually the length is 1. Remove both the assignments from the constructor. Then you will have a structure with zero members and the length will be correct.
You have a tail variable which should point to the last node in your list. You should be keeping it up to date:
class SingleLinkedList {
private Node head = null;
private Node tail = null;
public void addAtHead(int data) {
if (head == null) {
addFirst(data);
} else {
head.next = new Node(data, head.next);
if (tail == head)
tail = head.next;
}
}
public void addAtTail(int data) {
if (head == null) {
addFirst(data);
} else {
assert tail != null;
assert tail.next == null;
tail.next = new Node(data);
tail = tail.next;
}
}
private void addFirst(int data) {
assert head == null;
assert tail == null;
head = new Node(data);
tail = head;
}
}
If you want to remove the tail variable, then:
class SingleLinkedList {
private Node head = null;
public void addAtHead(int data) {
if (head == null) {
head = new Node(data);
} else {
head.next = new Node(data, head.next);
}
}
public void addAtTail(int data) {
if (head == null) {
head = new Node(data);
} else {
Node curr = head;
while (curr.next != null)
curr = curr.next;
curr.next = new Node(data);
}
}
}

Linked list node pointing to nodes of different type

This is my first post here, but I'm not new to the site (call me a lurker).
Unfortunately this time I cannot seem to find an answer to my question without asking.
Anyway, to the point.
I am writing a small snakes and ladders (aka chutes and ladders) program in java for a data structures course. I had to write my own Linked List (LL) class, (I know that there is a java util that does it better, but I have to learn about the workings of the data structure) and that is not a problem. My LL is 'semi-Double linked' as I like to call it, since it links forward, but has another pointer field for other links, which is not necessarily used in every node.
What I want to know is if it is possible to link a node from a list to another list, which is of a different type.
Poor example:
(eg.) How would one link a node of type to a node of type ? Let us say we have a LL of 7 int values [1,2,3,4,5,6,7], and a LL of 7 Strings [Monday, Tuesday, Wednesday,Thursday, Friday, Saturday, Sunday]. We want to link the node containing 1 to the node containing Monday.
To be exact the problem I am having is as follows:
I have 100 nodes forward-linked, forming the game board, and a circularly linked list of 4 . I want to link the player nodes to their respective positions on the board, so that as they traverse the board, they can also follow the "snakes" and "ladders" links.
Thanks in advance!
My LLNode.java and LL.java are attached.
// LLNode.java
// node in a generic linked list class, with a link
public class LLNode<T>
{
public T info;
public LLNode<T> next, link;
public LLNode()
{
next = null;
link= null;
}
public LLNode(T element)
{
info = element;
next = null;
link = null;
}
public LLNode(T element, LLNode<T> n)
{
info = element;
next = n;
link = null;
}
public T getInfo()
{
return info;
}
public void setInfo(T element)
{
info = element;
}
public LLNode<T> getNext()
{
return next;
}
public void setNext(LLNode<T> newNext)
{
next = newNext;
}
public LLNode<T> getLink()
{
return link;
}
public void setLink(LLNode<T> newLink)
{
link = newLink;
}
}
// SLL.java
// a generic linked list class
public class LL<T>
{
private LLNode<T> head, tail;
public LLNode<T> current = head;
public LL()
{
head = tail = null;
}
public boolean isEmpty()
{
return head == tail;
}
public void setToNull()
{
head = tail = null;
}
public boolean isNull()
{
if(head == tail)
if(head == null || tail == null)
return true;
else
return false;
else
return false;
}
public void addToHead(T element)
{
head = new LLNode<T>(element, head);
if (tail == null)
tail = head;
}
public void addNodeToHead(LLNode<T> newNode)
{
head = newNode;
if (tail == null)
tail = head;
}
public void addToTail(T element)
{
if (!isNull())
{
tail.next= new LLNode<T>(element);
tail = tail.next;
}
else head = tail = new LLNode<T>(element);
}
public void addNodeToTail(LLNode<T> newNode)
{
if (!isNull())
{
tail.next= newNode;
tail = tail.next;
}
else head = tail = newNode;
}
public void addBefore(T element, T X)
{
if (!isEmpty()) // Case 1
{
LLNode<T> temp, n;
temp = head;
while( temp.next != null )
{
if( temp.next.info == X )
{
n = new LLNode<T>(element, temp.next);
temp.next = n;
return;
}
else
temp = temp.next;
}
}
else // Case 2
head = new LLNode<T>(element, head);
}
public void addBefore(T element, LLNode<T> X)
{
if (!isEmpty()) // Case 1
{
LLNode<T> temp, n;
temp = head;
while( temp.next != null )
{
if( temp.next == X )
{
n = new LLNode<T>(element, X);
temp.next = n;
return;
}
else
temp = temp.next;
}
}
else // Case 2
head = new LLNode<T>(element, head);
}
public T deleteFromHead()
{
if (isEmpty())
return null;
T element = head.info;
if (head == tail)
head = tail = null;
else head = head.next;
return element;
}
public T deleteFromTail()
{
if (isEmpty())
return null;
T element = tail.info;
if (head == tail)
head = tail = null;
else
{
LLNode<T> temp;
for (temp = head; temp.next != tail; temp = temp.next);
tail = temp;
tail.next = null;
}
return element;
}
public void delete(T element)
{
if (!isEmpty())
if (head == tail && (element.toString()).equals(head.info.toString()))
head = tail = null;
else if ((element.toString()).equals(head.info.toString()))
head = head.next;
else
{
LLNode<T> pred, temp;
for (pred = head, temp = head.next; temp != null && !((temp.info.toString()).equals(element.toString())); pred = pred.next, temp = temp.next);
if (temp != null)
pred.next = temp.next;
if (temp == tail)
tail = pred;
}
}
public void listAll()
{
if(isNull())
System.out.println("\tEmpty");
else
{
for ( LLNode<T> temp = head; temp!= tail.next; temp = temp.next)
System.out.println(temp.info);
}
}
public LLNode<T> isInList(T element)
{
LLNode<T> temp;
for ( temp = head; temp != null && !((temp.info.toString()).equals(element.toString())); temp = temp.next);
return temp ;
}
public LLNode<T> getHead()
{
return head;
}
public LLNode<T> getTail()
{
return tail;
}
public LLNode<T> getCurrent()
{
return current;
}
public void incrementCurrent()
{
current = current.next;
}
public void followCurrentLink()
{
current = current.link;
}
}
Any specific reason you want to generics for the specific problem domain of the node objects?
If you want to have this effect, another way to do it might be have an interface for node object (maybe call it ILinkNode), have the getInfo and setInfo overridden in two different node classes. Then the nodeLink can point to interface object without special type casting everywhere in the code.
Use in the first list, i.e. the one containing the node you want to link to the node in the other list, Object as the generic type instantiation.
Something like:
LL<Object> ll = new LL<Object>();
If you do this, you have to take care to cast to the specific type, each time you retrieve a node's value from the list.

Categories