How to remove an element from the linked list?
Is it correct way:
public E remove(E element) {
Node search = currentNode;
boolean nonStop = true;
while(((search.previous) != null) && (nonStop)) {
if(search.previous.toString().equals(element.toString())) {
System.out.println("Item found !!!");
search.previous = search.previous.previous;
nonStop = false;
} else {
search = search.previous;
}
}
currentNode = search;
return null;
}
public class Node<E> {
public E data;
public Node<E> previous;
public Node(E data) {
this.data = data;
}
public void printNode() {
System.out.println("Node details: "+data);
}
#Override
public String toString() {
// TODO Auto-generated method stub
return (String)data;
}
}
The problem is when I am printing all elements, getAllElements() is NOT giving correct answer,is there any problem in remove() method or getAllElements
public void getAllElements() {
Node<E> aNode = currentNode;
while(aNode != null) {
aNode.printNode();
aNode = aNode.previous;
}
}
The line
if(search.previous.toString().equals(element.toString())
calls to string on the node and not on the element.
It seems like your remove method does not really remove anything, you should update the pointers in your method so that nothing points toward the element you want to remove, and then garbage collector will the remove the element that nothing points to. Some pseudocode to illustrate what I mean:
public remove(Element element){
for (Element e : myLinkedList){
if (e.equals(element)){
if (next != 0)
previousPtr = nextPtr;
else
previousPtr = null;
}
}
}
Note this is not correct Java code, just pseudocode to give you an idea, I save some fun for you!! :)
Try this:
public void remove(E element)
{
Node n = head; // This is the head of the linked list-- It is the starting node of your linked list: For your case "currentNode"
Node tmp;
while(n!=null && !n.data.equals(element))
{
tmp = n;
n = n.previous;
}
if(n==null)
{
// Do your stuff
System.out.println("Element "+element+" not found.");
}
else
{
// Do your stuff
tmp.prev = n.prev;
n.prev = null;
System.out.println("Element "+element+" removed.");
}
}
// Suggestion: This method name should be "printList()"
public void getAllElements()
{
Node n = head; // In your case: "currentNode"
while(n!=null)
{
n.printNode();
n = n.previous;
}
}
Don't your elements have some kind of identifier?
Then you can do it much simpler, like here: remove an object
public E remove(E element) {
Node search = currentNode;
boolean nonStop = true;
while(((search.previous) != null) && (nonStop)) {
if(search.previous.data.equals(element)) {
System.out.println("Item found !!!");
search.previous = search.previous.previous;
nonStop = false;
}
search = search.previous;
}
return null;
}
I have found the solution for that Issue, thanks everyone for yours kind support.
Related
Guys I am a newbie and i am learning data structures.I am learning Linked list implementation of stack and I wrote this code below for the implementation.
the push method works fine but the pop method doesnt works fine and doesnt deletes the node.
public class Slink {
Node head;
public void push(int 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 pop()
{
if(head==null)
{
System.out.println("Stack has 0 items .. cant delete");
}
else {
Node n = head;
while (n.next != null) {
n = n.next;
}
n=null;
}
}
public void show()
{
Node n=head;
while(n.next!=null)
{
System.out.println(n.data);
n=n.next;
}
System.out.println(n.data);
}
}
Now using this in a class.
public class Sll {
public static void main(String[] args) {
Slink stk=new Slink();
stk.push(4);
stk.push(54);
stk.push(23);
stk.push(90);
stk.pop();
stk.show();
}
}
The output is
4
54
23
90
while 90 should have been removed.
Guys please tell me where i am wrong and correct me.
Thanks
n=null; in your pop() method modifies nothing else than the value of your scoped n variable. You will instead want to set n.next=null on the last node which has a non-null next.
It can be done in the following way for example :
public void pop()
{
if(head==null)
{
System.out.println("Stack has 0 items .. cant delete");
}
else if(head.next == null) {
head = null;
}
else {
Node n = head;
while (n.next != null && n.next.next != null) {
n = n.next;
}
n.next=null;
}
}
You can try it here. (I've also fixed your show() method to work correctly with empty stacks)
In pop method instead of:
Node n = head;
while (n.next != null) {
n = n.next;
}
n=null;
Try:
head = head.next();
Actually, you did not mention your node(), class. It seems that you didn't make tail node which is necessary for the link list.
I think this code will definitely help you
Pop() method
public void pop() {
node current = header;
node back = null;
while ((current != null)) {
if ((current == tail)) {
back.next = null;
tail = back;
break;
}
else {
back = current;
current = current.next;
}
Node Class
class node {
public int data;
public node next;
public node(int data) {
this.data = this.data;
this.next = null;
}
}
Do some changes in Push method
public void push(int data) {
node nnew = new node(data);
if ((header == null)) {
header = nnew;
tail = nnew;
}
else {
tail.next = nnew;
tail = tail.next;
}
}
public class LinkedList<T>
{
private Node head;
private int size;
public LinkedList()
{
}
public void addToHead(T value) // create new node, make new node point to head, and head point to new node
{
if (head == null)
{
head = new Node(value,null);
}
else
{
Node newNode = new Node(value,head);
head = newNode;
}
size++;
}
public boolean isEmpty()
{
return head == null;
}
public int size()
{
return size;
}
public void removeHead()
{
head = head.next;
size--;
}
public void addToTail(T value)
{
if (isEmpty())
{
System.out.println("You cannot addtoTail of a emptyList!");
}
else
{
System.out.println(value);
Node current = head;
System.out.println("we are pointing to head: "+current);
while (current.getNext() != null) // loop till the end of the list (find the last node)
{
System.out.println("we are now pointing to: "+current.getElement());
current = current.getNext();
}
System.out.println("We are at the last node:"+current); // its working
System.out.println("it should point to null:"+current.getNext()); // its working
current.setNext(new Node(value,null)); // make it point to our new node we want to insert
System.out.println(current.getNext()); // it is pointing to the new node.. yet the node is not actually inserted (local variable problem? )
size++;
}
}
public String toString()
{
String output = "";
if (!isEmpty())
{
Node current = head;
output = "";
while (current.getNext() != null)
{
output += current.toString()+ "->";
current = current.getNext();
}
}
return output;
}
protected class Node
{
private T element;
private Node next;
public Node()
{
this(null,null);
}
public Node(T value, Node n)
{
element = value;
next = n;
}
public T getElement()
{
return element;
}
public Node getNext()
{
return next;
}
public void setElement(T newElement)
{
element = newElement;
}
public void setNext(Node newNext)
{
next = newNext;
}
public String toString()
{
return ""+element;
}
}
}
So I have written this linkedlist class, and every method works except addtoTail. For example say I create a instance of my linkedlist class, and call addToHead(5), then addtoTail(6) and use my toString method to print out the linkedlist, it only contains 5->. I debugged the addToTail and everything seems to be pointing to the correct locations, yet for some reason it does not add the new node (6) to the list. Hopefully I explained that clearly. I am probably missing something really simple (I even drew it on paper to visualize it but do not see the problem).
Your addToTail function is probably fine. I think the culprit is your toString function. In particular, in this snippet:
while (current.getNext() != null)
{
output += current.toString()+ "->";
current = current.getNext();
}
Your condition terminates the loop before reaching the end. What you actually want is:
while(current != null) {
....
}
please help me to understand how does the method delete (with specifying value) work?
I understood everything except this point.
I wrote method delete but don't understand how changing field next in Link "previous" weigh with Link first, I know that the next Link will be missed, but this Link also will be missed in the first List. (it means that I don't understand how to reference type work)
package Book.LinkedList;
/**
* Created by Сергей on 06.07.2015.
*/
public class Link {
Link(int serial) {
this.serial = serial;
next = null;
}
private int serial;
private Link next;
public void setSerial(int serial) {
this.serial = serial;
}
public int getSerial() {
return serial;
}
public void setNext(Link tmp) {
next = tmp;
}
public Link getNext() {
return next;
}
public void display() {
System.out.print(serial + " ");
}
}
package Book.LinkedList;
public class LinkList {
LinkList() {
first = null;
}
private Link first;
public boolean isEmpty() {
return first == null;
}
public void insertFirst(int serial) {
Link newLink = new Link(serial);
if(first == null ) { newLink.setNext(null); }
else {
newLink.setNext(first);
}
first = newLink;
}
public void deleteFirst(){
if( isEmpty() == false){
first = first.getNext();
System.out.println("The link was successfully deleted!");
}
else {
System.out.println("The LinkList is empty, we can't delete element!");
}
}
public boolean find(int key) {
Link current = first;
if (current == null) {
System.out.println("The list is empty.");
return false;
}
do {
if (current.getSerial() == key) {
return true;
}
else {
current = current.getNext();
}
}
while (current != null);
return false;
}
// delete chosen/ selected element
// пока не понятно как данное удаление влияет именно на first, почему удаляется из first
public void delete(int key) {
Link previous = null;
Link current = first;
if (current == null) {
System.out.println("The list is empty.");
return;
}
do {
if (current.getSerial() == key) {
if(previous == null) { first = first.getNext(); return;}
else {
previous.setNext(current.getNext());
return;
}
}
else {
previous = current;
current = current.getNext();
}
}
while (current != null);
System.out.println("There isn't element with entered serial;");
}
public void displayList() {
Link current = first;
while(current != null) {
current.display();
current = current.getNext();
}
System.out.println("The linkList was successfully displayed");
}
}
You can imagine it better visually:
We make the next link skip a step in the chain, and then we simply remove the no longer needed node. Though in this case we is a bit misleading, as we never invoke deletion directly. We are just removing all references of the node, so the garbage collector will remove it after a while.
Pseudocode for this algorithm
IF the first element is null, then the list empty, DONE
IF the next element is to be removed THEN
IF the element to be removed is the first one: first = first.next() and DONE,
ELSE its not he first: just skip the node and DONE
ELSE GOTO 2.
If we got here, there was no matching element
What you need to see, that in both cases where the done is highlighted, all references are lost to the node.
Hey ya'll I am having a little trouble with my singly linked list. I decided to create a simple one because we do not get enough practice during my data structures class and cannot seem to find why I am not getting the right output.
The code is:
package linked_list;
public class LinkedList {
private Node head;
private Node tail; // After figuring out head, come back to this FIXME
private int listSize;
public LinkedList() {
head = new Node(null);
tail = new Node(null);
}
public void addLast(String s) {
Node newNode = new Node(s);
if (head == null) {
addFirst(s);
} else {
while (head.next != null) {
head = head.next;
}
head.next = newNode;
tail = newNode;
}
listSize++;
}
public void addFirst(String s) {
Node newNode = new Node(s);
if (head == null) {
head = newNode;
tail = newNode;
}
else {
newNode.next = head;
head = newNode;
}
listSize++;
}
public Object getFirst() {
return head.data;
}
public Object getLast() {
return tail.data;
}
public void clear() {
head = null;
tail = null;
listSize = 0;
}
public Object peek() {
try {
if (head == null) {
throw new Exception ("The value is null");
}
else {
return head;
}
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
public int size() {
return listSize;
}
// This class has the ability to create the nodes that are used
// in the Linked List.
private class Node {
Node next;
Object data;
public Node(String value) {
next = null;
data = value;
}
public Node(Object value, Node nextValue) {
next = nextValue;
data = value;
}
public Object getData() {
return data;
}
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
}
Now here is my driver that I created to run a simple little operation:
package linked_list;
public class LinkedListDriver {
public static void main(String[] args) {
LinkedList list1 = new LinkedList();
list1.clear();
list1.addLast("This goes last");
list1.addFirst("This goes first");
list1.addLast("Now this one goes last");
System.out.println(list1.getFirst());
System.out.println(list1.getLast());
}
}
My output is this:
This goes last
Now this one goes last
I guess my question is why am I not getting the answer This goes first from my getFirst() method. It seems to be something wrong with the order or structure of that method but I cannot pinpoint it.
When you are in the else in the addLast, you are changing the reference to head. You should use another reference pointer to traverse the list when adding in the else.
Also, your list size should only be incremented in the else in addLast because you are incrementing twice otherwise (once in addFirst and again after the if-else in addLast).
I am working on a homework assignment involving linked lists. We have to implement a queue ADT, and the one method I am having trouble with is adding a node to the end of the list (the enqueue method). Here is my code:
public class Queue implements QueueInterface {
private Node head;
private Node tail;
private int sz;
public Queue() {
head = null;
tail = null;
sz = 0;
}
public void enqueue(T newEntry) {
Node newElement = new Node(newEntry);
newElement.next = null;
tail.next = newElement;
tail = newElement;
}
public T dequeue() {
T result = null;
if(head != null) {
result = head.data;
head = head.next;
sz--;
}
return result;
}
public T getFront() {
return head.data;
}
public boolean isEmpty() {
if (head == null) {
return true;
}
return false;
}
public void clear() {
while (!isEmpty()) {
dequeue();
}
}
#Override
public String toString() {
return "Queue [head=" + head + ", sz=" + sz + "]";
}
public class Node {
private Node next;
private T data;
public Node (T newData) {
data = newData;
}
#Override
public String toString() {
return "Node [next=" + next + ", data=" + data + "]";
}
}
}
If anyone could help me out with this I would be really appreciative. Thanks for your time! :)
You aren't handling the case where the list is empty. You're adding the first item, tail is null and you're getting the appropriate exception.
You need to check tail to see if it's null before attempting to use it, and act appropriately if that is the case. Don't forget to set head as well.
You don't need this line, next should already be null.
newElement.next = null;
You also forgot to incremement sz after your enqueue.
If you try and enqueue to an empty linked list what happens? You're going to have to deal with that case, it is why you are getting a NullPointerException
public void enqueue(T newEntry) {
Node newElement = new Node(newEntry);
newElement.next = null;
if(tail != null)
{
tail.next = newElement;
tail = newElement;
}else
{
head=tail=newElement;
}
}
Check if tail is null or not. if tail is null it means this is the first node. add this as first node. as add after the tail.
Your enqueue method tries to set tail.next to newElement. What happens if the tail hasn't been initialized yet? You'll get a NullPointerException.