I realize this should be a very easy method to implement and I have no idea why this code is not working.
I get a NullPointerException at tail.next = node. If it is not commented out, it does not pass the tester.
public void addBack (int x)
{
IntegerNode node = new IntegerNode(x,null);
if (head == null)
head = node;
else{
node.prev = tail;
//tail.next = node;
tail = node;
}
count++;
}
When the list is empty, set your head and tail to the new element. Should be ok after that, though more null checks are rarely a bad idea.
if (head == null) {
head = node;
tail = node;
} else {
node.prev = tail;
tail.next = null; // Did you really mean tail.next = node? This looks more likely..
tail = node;
}
Related
This method will create a new Node object and insert it in order by the 3rd value in the CSV(i.e. KYZ98765, ABC12345, etc.) it works except for the last node insert...
Here is my code:
void sortedInsert(Node new_node)
{
Node current;
/* Locate the correct node before inserting. */
//System.out.println(current.data);
if(head.next == null)
{
new_node.next = head;
head = new_node;
System.out.println("Inserted head: \n" + head.data.toString());
}else
{
current = head;
while (current.data.getbLnum().compareTo(new_node.data.getbLnum())>=0)
{
System.out.println("here again");
current = current.next;
}
new_node.next = current.next;
current.next = new_node;
System.out.println("Inserted: \n" + current.next.data.toString());
}
}
Here is the output:
FundManagerLicense FundManagerLastname FundManagerFirstname
ABC12345 Wonch Bob
FundManagerLicense FundManagerLastname FundManagerFirstname
ZYK98765 Ferguson Jesus
FundManagerLicense FundManagerLastname FundManagerFirstname
GYZ98765 Ferguson Jose
FundManagerLicense FundManagerLastname FundManagerFirstname
KYZ98765 Ferguson Jimmi
This is my input in the order each element is fed to the sortedInsert:
BROKER,ADD,KYZ98765,Jimmi,Ferguson,321-131,0.02
BROKER,ADD,ABC12345,Bob,Wonch,321-112,0.1
BROKER,ADD,GYZ98765,Jose,Ferguson,321-111,0.02
BROKER,ADD,ZYK98765,Jesus,Ferguson,321-141,0.02
Can anyone see what is going wrong?
Try it this way.
private int compare(Node n1, Node n2) {
return n1.data.getbLnum().compareTo(n2.data.getbLnum());
}
void sortedInsert(Node newNode) {
Node prev = null;
Node next = head;
while (next != null &&
compare(newNode, next) >= 0) {
prev = next;
next = next.next;
}
if (prev == null) head = newNode;
else prev.next = newNode;
newNode.next = next;
}
It should be fairly self-explanatory, go through the list, keeping track of the nodes that will come before (prev) and after (next) the inserted node, until next is null, or until newNode cannot come after next. Then insert the new node and, if necessary, make it the head.
You have a big risk of a null pointer exception.
while (current.data.getbLnum().compareTo(new_node.data.getbLnum())>=0)
{
System.out.println("here again");
current = current.next;
}
When you reach the end of your list current will become null and the next call to current.data will throw and exception.
Do you know why is not being thrown? Because you made your list a circular list!
new_node.next = head;
head = new_node;
The new node is the head and point to itself as next. So your last insertion goes all the way to the end f the list, fails to find an insertion place (because your last input should be placed at the end of the list) and then became the next after the head.
To solve the problem you need two changes:
void sortedInsert(Node new_node){
Node current;
/* Locate the correct node before inserting. */
//System.out.println(current.data);
if(head.next == null)
{
new_node.next = **null**;
head = new_node;
System.out.println("Inserted head: \n" + head.data.toString());
}else
{
current = head;
while (current.data.getbLnum().compareTo(new_node.data.getbLnum())>=0 **&& current.next != null**)
{
System.out.println("here again");
current = current.next;
}
new_node.next = current.next;
current.next = new_node;
System.out.println("Inserted: \n" + current.next.data.toString());
}
}
Test them and let me know.
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;
}
}
}
I solved the next exercises having two solutions: https://www.hackerrank.com/challenges/reverse-a-doubly-linked-list
First (non-recursive):
/*
Insert Node at the end of a linked list
head pointer input could be NULL as well for empty list
Node is defined as
class Node {
int data;
Node next;
Node prev;
}
*/
Node Reverse(Node head) {
if (head == null) return null;
Node current = head;
while (current.next != null) {
Node temp = current.next;
current.next = current.prev;
current.prev = temp;
current = temp;
}
current.next = current.prev;
current.prev = null;
return current;
}
Second algorithm (recursive):
/*
Insert Node at the end of a linked list
head pointer input could be NULL as well for empty list
Node is defined as
class Node {
int data;
Node next;
Node prev;
}
*/
Node Reverse(Node head) {
if (head.next == null) {
head.next = head.prev;
head.prev = null;
return head;
}
Node newHead = Reverse(head.next);
Node temp = head.next;
head.next = head.prev;
head.prev = temp;
return newHead;
}
According to the book, the solution must be O(n). I guess using recursive solution is more elegant but maybe I'm wrong. Can you help to determine the space and time complexity of these two algoritms, or in your, which is better in performance?
The question is a bit unclear, both solutions seem to be O(n) in both time and space. Although you could probably remove the special cases and make Torvalds happy. Something like:
Node Reverse(Node head) {
if (head == null) return null;
Node current = head;
while (current != null) {
Node temp = current.next;
current.next = current.prev;
current.prev = temp;
current = temp;
}
return current;
}
Node Reverse(Node head) {
Node temp = head.next;
head.next = head.prev;
head.prev = temp;
return temp==null?head:Reverse(temp);
}
I have not tested these, use them as inspiration only. (Also the recursive will nullpointer if head is null in the beginning).
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;
}
Node class
private class Node<E> {
E data;
Node<E> next;
public Node(E obj) {
data = obj;
next = null;
}
}
insert method (ascending order)
public void insert(E obj) {
Node<E> newNode = new Node<E>(obj);
Node<E> prev = null, curr = head;
while(curr != null && ((Comparable<E>)obj).compareTo(curr.data) >= 0) {
prev = curr;
curr = curr.next;
}
if(prev == null)
head = newNode;
else {
prev.next = newNode;
newNode.next = curr;
}
currentSize++;
}
remove method
public E remove() {
if(isEmpty())
return null;
E tmp = head.data;
head = head.next;
currentSize--;
return tmp;
}
I get Null Pointer Exception at the line
E tmp = head.data;
in the remove method
The error is fixed if the change the else statement in my insert method to
else
prev.next = newNode;
newNode.next = curr;
There's a problem when you insert a new node that needs to go at the beginning of the list (because it's smaller than the current head node). When you get to this part:
if(prev == null)
head = newNode;
you're setting head to be the new node you've just created, but you also need to set newNode.next to be the previous head. So you really want
if(prev == null) {
newNode.next = head;
head = newNode;
}
which inserts the new node at the beginning but tacks the previous head onto it.
With your code as it stands, when you add a second element that should go at the beginning, you're accidentally discarding the element that's already there, but you're still increasing currentSize; so you end up with a list with only one element, but a currentSize of 2. When you then try to remove two elements, the second one fails with a NullPointerException because you try to read the data inside a non-existent element.