How to debug my Java linked-list queue? - java

I had basically no issue with linked lists in C++, but this is getting to me for some reason. I had a single node being printed out using the other classes in the package that were provided, but as I go on I just keep running into walls.
The code below is in shambles due to me tinkering around. I just have no idea where to go from here. As of now that is getting a null pointer exception.
Just for information: poll() is just removing the current head and returning it, offer() is adding to the rear. As of now the exception is at oldLast.next = last in the offer method.
I am not asking for anyone to completely solve this. I just need some tips to progress.
public class FIFOQueue implements Queue {
//put your name as the value of the signature.
String signature = "name";
Node head = new Node(null);
Node pointer = head;
Node first;
Node last;
Node prev;
Node curr;
class Node {
Process process;
Node next;
Node(Process p) {
this.process = p;
this.next = null;
}
}
#Override
public void offer(Process p) {
if(head == null)
{
head = new Node(p);
first = head;
last = head;
}
else
{
Node oldLast = last;
Node newNode = new Node(p);
last = newNode;
oldLast.next = last;
}
}
#Override
public Process poll() {
if(isEmpty())
throw new NoSuchElementException();
Node oldPointer = first;
first = first.next;
head = first;
return oldPointer.process;
}
#Override
public boolean isEmpty() {
return head == null;
}
#Override
public String getSignature() {
return signature;
}
}

I think your core issue is here:
Node prev;
Node curr;
These are confusing you. Remove them.
Node prev; - This should be in the Node class.
Node curr; - This should be a local variable, not an instance variable.
Also
Node head = new Node(null);
does not gel with
if(head == null)
{
head = new Node(p);
Either make head == null mean the list is empty or something else - but be consistent.

(Posted on behalf of the OP).
public void offer(Process p) {
if(head.process == null)
{
head = new Node(p);
first = head;
last = head;
}
last.next = new Node(p);
last = last.next;
}
This solved my issue. Can't believe I let this confuse me.

Related

write a function to add to the end of linked list [duplicate]

I'm studying for an exam, and this is a problem from an old test:
We have a singly linked list with a list head with the following declaration:
class Node {
Object data;
Node next;
Node(Object d,Node n) {
data = d;
next = n;
}
}
Write a method void addLast(Node header, Object x) that adds x at the end of the list.
I know that if I actually had something like:
LinkedList someList = new LinkedList();
I could just add items to the end by doing:
list.addLast(x);
But how can I do it here?
class Node {
Object data;
Node next;
Node(Object d,Node n) {
data = d ;
next = n ;
}
public static Node addLast(Node header, Object x) {
// save the reference to the header so we can return it.
Node ret = header;
// check base case, header is null.
if (header == null) {
return new Node(x, null);
}
// loop until we find the end of the list
while ((header.next != null)) {
header = header.next;
}
// set the new node to the Object x, next will be null.
header.next = new Node(x, null);
return ret;
}
}
You want to navigate through the entire linked list using a loop and checking the "next" value for each node. The last node will be the one whose next value is null. Simply make this node's next value a new node which you create with the input data.
node temp = first; // starts with the first node.
while (temp.next != null)
{
temp = temp.next;
}
temp.next = new Node(header, x);
That's the basic idea. This is of course, pseudo code, but it should be simple enough to implement.
public static Node insertNodeAtTail(Node head,Object data) {
Node node = new Node(data);
node.next = null;
if (head == null){
return node;
}
else{
Node temp = head;
while(temp.next != null){
temp = temp.next;
}
temp.next = node;
return head;
}
}
If you keep track of the tail node, you don't need to loop through every element in the list.
Just update the tail to point to the new node:
AddValueToListEnd(value) {
var node = new Node(value);
if(!this.head) { //if the list is empty, set head and tail to this first node
this.head = node;
this.tail = node;
} else {
this.tail.next = node; //point old tail to new node
}
this.tail = node; //now set the new node as the new tail
}
In plain English:
Create a new node with the given value
If the list is empty, point head and tail to the new node
If the list is not empty, set the old tail.next to be the new node
In either case, update the tail pointer to be the new node
Here is a partial solution to your linked list class, I have left the rest of the implementation to you, and also left the good suggestion to add a tail node as part of the linked list to you as well.
The node file :
public class Node
{
private Object data;
private Node next;
public Node(Object d)
{
data = d ;
next = null;
}
public Object GetItem()
{
return data;
}
public Node GetNext()
{
return next;
}
public void SetNext(Node toAppend)
{
next = toAppend;
}
}
And here is a Linked List file :
public class LL
{
private Node head;
public LL()
{
head = null;
}
public void AddToEnd(String x)
{
Node current = head;
// as you mentioned, this is the base case
if(current == null) {
head = new Node(x);
head.SetNext(null);
}
// you should understand this part thoroughly :
// this is the code that traverses the list.
// the germane thing to see is that when the
// link to the next node is null, we are at the
// end of the list.
else {
while(current.GetNext() != null)
current = current.GetNext();
// add new node at the end
Node toAppend = new Node(x);
current.SetNext(toAppend);
}
}
}
loop to the last element of the linked list which have next pointer to null then modify the next pointer to point to a new node which has the data=object and next pointer = null
Here's a hint, you have a graph of nodes in the linked list, and you always keep a reference to head which is the first node in the linkedList.
next points to the next node in the linkedlist, so when next is null you are at the end of the list.
The addLast() needs some optimisation as the while loop inside addLast() has O(n) complexity. Below is my implementation of LinkedList. Run the code with ll.addLastx(i) once and run it with ll.addLast(i) again , you can see their is a lot of difference in processing time of addLastx() with addLast().
Node.java
package in.datastructure.java.LinkedList;
/**
* Created by abhishek.panda on 07/07/17.
*/
public final class Node {
int data;
Node next;
Node (int data){
this.data = data;
}
public String toString(){
return this.data+"--"+ this.next;
}
}
LinkedList.java
package in.datastructure.java.LinkedList;
import java.util.ArrayList;
import java.util.Date;
public class LinkedList {
Node head;
Node lastx;
/**
* #description To append node at end looping all nodes from head
* #param data
*/
public void addLast(int data){
if(head == null){
head = new Node(data);
return;
}
Node last = head;
while(last.next != null) {
last = last.next;
}
last.next = new Node(data);
}
/**
* #description This keep track on last node and append to it
* #param data
*/
public void addLastx(int data){
if(head == null){
head = new Node(data);
lastx = head;
return;
}
if(lastx.next == null){
lastx.next = new Node(data);
lastx = lastx.next;
}
}
public String toString(){
ArrayList<Integer> arrayList = new ArrayList<Integer>(10);
Node current = head;
while(current.next != null) {
arrayList.add(current.data);
current = current.next;
}
if(current.next == null) {
arrayList.add(current.data);
}
return arrayList.toString();
}
public static void main(String[] args) {
LinkedList ll = new LinkedList();
/**
* #description Checking the code optimization of append code
*/
Date startTime = new Date();
for (int i = 0 ; i < 100000 ; i++){
ll.addLastx(i);
}
Date endTime = new Date();
System.out.println("To total processing time : " + (endTime.getTime()-startTime.getTime()));
System.out.println(ll.toString());
}
}
The above programs might give you NullPointerException. This is an easier way to add an element to the end of linkedList.
public class LinkedList {
Node head;
public static class Node{
int data;
Node next;
Node(int item){
data = item;
next = null;
}
}
public static void main(String args[]){
LinkedList ll = new LinkedList();
ll.head = new Node(1);
Node second = new Node(2);
Node third = new Node(3);
Node fourth = new Node(4);
ll.head.next = second;
second.next = third;
third.next = fourth;
fourth.next = null;
ll.printList();
System.out.println("Add element 100 to the last");
ll.addLast(100);
ll.printList();
}
public void printList(){
Node t = head;
while(n != null){
System.out.println(t.data);
t = t.next;
}
}
public void addLast(int item){
Node new_item = new Node(item);
if(head == null){
head = new_item;
return;
}
new_item.next = null;
Node last = head;
Node temp = null;
while(last != null){
if(last != null)
temp = last;
last = last.next;
}
temp.next = new_item;
return;
}
}

How can I initialize a Doubly Linked List and then add the first element in java?

I'm currently working on creating a doubly linked list, but I'm struggling to do so because the constructor requires the previous element and the next element. However, checking the list just results in two null elements, the head and the tail. The constructor for a node is
public Node(Node prev, Node next, String link) {
this.prev = prev;
this.next = next;
this.link = link;
}
The constructor for the empty list that I have is
public DoublyLinkedList() {
head = tail = null;
}
My code for adding an element is
public void addElement(String link) {
Node n = new Node(tail.prev, tail, link);
if (head == null) {
head = n;
head.next = n;
}
tail.prev = n;
tail = n;
}
I know that the reason I'm resulting in null is because tail == null when I pass it into the constructor. However, I don't know how to update the value of tail before creating a new Node. I tried constructing the empty list with
public DoublyLinkedList() {
head = tail = null;
head.prev = null;
head.next = tail;
tail.next = null;
tail.prev = head;
}
But that isn't showing the elements as being added either.
Am going to assume that addElement adds an element to the end of the list
if that is the case try this instead
Node n = new Node(tail, null, link); // The new tail
if (head == null) {
head = n;
tail = n;
}else{
tail.next = n;
tail = n;
}
For that you can create a class like this:
Just for start.
public class DLinkedList{
private node pHead;
private node pTail;
public DLinkedList()
{
this.pHead=null;
this.pTail=null;
}
public insert(String newLink)
{
node newNode = new node():
newNode.link = newLink;
if(pHead==null)
{
pHead=newNode;
pTail=pHead;
}
else
{
newNode.prev=pTail;
pTail.next=newNode;
pTail= pTail.next;
}
}
}

reverse the order of the entire list for doubly linkedList

I was reading about queues in java implementation. I want to implement the following task:
public class DoublyLinkedList
{
private Node first; // the first Node in the list
private Node last; // the last Node in the list
private class Node
{
private Point p;
private Node prev; // the previous Node
private Node next; // the next Node
}
public void reverse()
{
// your code
}
}
I did like this:
public void reverse() { // that reverses the order of the entire list
if (first == null && last == null) {
throw new RuntimeException();
}
Node current = first;
while (current!=null) {
current.next= current.next.prev;
current.prev=current.prev.next;
current=current.next;
}
}
Am I doing right?
thanks
You don't change the first and last pointer in your code. Why are you throwing an exception if the list is empty?
I guess I would do something like:
public void reverse()
{
Node current = first;
while (current != null) {
Node next = current.next;
current.next = current.prev;
current.prev = next;
current = next;
}
Node temp = first;
first = last;
last = temp;
}
No it is not. current.next = current.next.prev is like current.next = current and current.prev = current.prev.next is like current.prev = current. Please attach a debugger and follow your code to find the errors and the right solution. We won't do your homework here. ;-)

Issues with reversing the linkedlist

I'm trying to learn about linked list and it has been little challenging for me. I'm trying to reverse the link list with recursive method. Here is my code:
public class ListNode {
Node head = null;
int nodeCount= 0;
int counter = 0;
ListNode(){
head = null;
}
public void insertNode( String name ) {
if (head == null) {
head = new Node(name, null);
nodeCount++;
} else {
Node temp = new Node(name, null);
temp.next = head;
head = temp;
nodeCount++;
}
}
public Node reverseTest(Node L){
// Node current = new Node(null,null);
if(L == null || L.next ==null){
return L;
}
Node remainingNode = reverseTest(L.next);
Node cur = remainingNode;
while(cur.next !=null){
cur=cur.next;
}
L.next = null;
cur.next = L;
return remainingNode;
}
public static void main(String[] args){
ListNode newList = new ListNode();
newList.insertNode("First");
newList.insertNode("Second");
newList.insertNode("Third");
newList.insertNode("Fourth");
newList.reverseTest(newList.head);
}
}
The problem I'm having with is the reverse method. When the method is over it only returns the last node with the value "First".Through the entire recursion remainingNode only holds and returs value from the base case which is confusing me. I was excepting it to move further through the nodes. After the method is executed newList holds only one node with next node as null and that node is the head now. I was assuming it will reverse the linkedlist with the sequence First --> Second--> Third --> Fourth. What am I doing wrong?
Actually, everything works here. Your only problem is in your main method: you don't get the result of your method.
newList.reverseTest(newList.head);
You need to actually set the new head with the result:
newList.head = newList.reverseTest(newList.head);
This would have been easier to see if you had declared your method static:
newList.head = ListNode.reverseTest(newList.head);
As a bonus, here is a fully recursive equivalent:
public static Node reverse(Node head) {
if (head == null || head.next == null) {
return head;
}
Node newHead = reverse(head.next);
// head.next points to the new tail, we push the former head at the end
head.next.next = head;
// now head has become the new tail, we cut the end of the list
head.next = null;
return newHead;
}

What is LinkedListNode in Java

Excuse my ignorance but I am beginning to prepare for my first technical interview and came across this question and answer on the topic linkedlist
Question: Implement an algorithm to delete a node in the middle of a single linked list, given only access to that node
public static boolean deleteNode(LinkedListNode n) {
if (n == null || n.next == null) {
return false; // Failure
}
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
return true;
}
I want to start playing with this code (making changes compile test) but I'm not sure how to start doing this in Java. I cannot find the LinkedListNode class in Java docs.
This might be a very silly question but if someone can point me in the right direction - will appreciate it.
EDIT
Thanks for the quick and useful responses. I guess my question was not very clear. The algorithm above was provided as a solution to that question. I wanted to know how to implement that in Java so I can play around with the code.
thanks
The code will only work properly if there's a tail node on the list.
The algorithm works with the following logic
When referring to the node to be deleted, call it "curr"
When referring to the node before "curr", call it "prev"
When referring to the node after "curr", call it "next"
To effectively delete our node, "prev".next should point to "next"
It currently points to "curr"
Our problem is that we have no reference to "prev"
We know "prev".next points to "curr"
Since we cannot change the fact that "prev".next points to "curr",
we must have "curr" gobble up "next"
We make "curr"s data be "next"s data
We make "curr"s next be "next"s next
The reason this only works if there's a tail guard
is so we can make "next" be the "tail" node of the
list. (Its data is null and it's next is null.) Otherwise,
"prev".next would still be pointing to something.
Here's a class that uses LinkedListNode. I should note that if you're applying for a position as a programmer, you should be able to do this basically from memory. :-)
class LinkedList<E> {
static class LinkedListNode<E> {
E data;
LinkedListNode<E> next;
}
/**
* Not exactly the best object orientation, but we'll manage
*/
static <E> E deleteNode(LinkedListNode<E> node) {
if(node == null || node.next == null) return null;
E retval = node.data;
LinkedListNode<E> next = node.next;
node.data = next.data;
node.next = next.next;
return retval;
}
private LinkedListNode<E> head;
private LinkedListNode<E> tail;
public LinkedList() {
this.head = new LinkedListNode<E>();
this.tail = new LinkedListNode<E>();
head.next = tail;
}
public void addLast(E e) {
LinkedListNode<E> node = new LinkedListNode<E>(); // e and next are null
tail.data = e;
tail.next = node;
tail = node;
}
public void addFirst(E e) {
LinkedListNode<E> node = new LinkedListNode<E>(); // e and next are null;
node.next = head.next;
node.data = e;
head.next = node;
}
public E deleteFirst() {
LinkedListNode<E> first = head.next;
head.next = first.next;
return first.data;
}
public E deleteLast() {
// cannot do without iteration of the list! :-(
throw new UnsupportedOperationException();
}
public LinkedListNode<E> findFirst(E e) {
LinkedListNode<E> curr = head.next;
while(curr != null) {
if(curr.data != null && curr.data.equals(e)) return curr;
curr = curr.next;
}
return null;
}
public void print() {
LinkedListNode<E> curr = head.next;
while(curr.next != null) {
System.out.println(curr.data);
curr = curr.next;
}
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.addLast("Apple");
list.addLast("Bear");
list.addLast("Chair");
list.addLast("Dirt");
//list.print();
LinkedListNode<String> bear = list.findFirst("Bear");
deleteNode(bear);
list.print();
}
}
This class is most likely a hypothetical class used for this Linked List example question.
LinkedListNode is a class that you will define to hold data. To get your above example to work - I've quickly written this code (just to make you understand the simple concept) in which I am creating 3 nodes (which are linked to each other) and then deleting the middle one calling the deleteNode method that you have specified in your question.
The code is pretty self explanatory. Let me know if this helps.
Good Luck
class LinkedListNode
{
public Object data;
public LinkedListNode next;
public LinkedListNode(Object data) {
this.data = data;
}
}
class DeleteNodeLinkedList
{
public static void main(String[] args)
{
LinkedListNode node_1 = new LinkedListNode("first");
LinkedListNode node_2 = new LinkedListNode("second");
node_1.next = node_2;
LinkedListNode node_3 = new LinkedListNode("third");
node_2.next = node_3;
System.out.println("*** Print contents of linked list");
LinkedListNode current = node_1;
while (current != null) {
System.out.println(current.data);
current = current.next;
}
System.out.println("*** Now delete second node");
deleteNode(node_2);
System.out.println("*** Print after deleting second node");
current = node_1;
while (current != null) {
System.out.println(current.data);
current = current.next;
}
}
public static boolean deleteNode(LinkedListNode n)
{
if (n == null || n.next == null) {
return false; // Failure
}
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
return true;
}
}
The important details in this question pertain to data structures, java is just the language that is being used to implement in this case.
You should read the wikipedia article about linked lists, and for this question be careful that your solution doesn't produce any dangling references or orphan nodes.
Do some searches on the two terms in bold, and make sure that you understand them
Your question is bit confusing. whether you want a logic to remove a node in a singly linkedlist or you want to learn and use java LinkedlistNode.
if you are in second the following link will help you
LinkedListNodee
or if you want the logic
let P the pointer to the current node
P->data = P->next->data
Q=P->next
P->next=Q->next
delete(Q)

Categories