Doubly linked list does not print backwards - java

In below doubly linked list example I can add node to front of the doubly linked list and the end of the doubly linked list. I also can traverse the doubly linked list forward and print the node's value successfully. Hoewer when I print the list backwards my tail.previous value is null and I can print only the node's value that is currently in the tail Could you please tell what is wrong. Thank you.
public class DLL {
public Node head;
public Node tail;
/* Doubly Linked list Node*/
public class Node {
public int data;
public Node prev;
public Node next;
// Constructor to create a new node
// next and prev is by default initialized as null
Node(int d) { data = d; }
}
public void addToFront(int data){
System.out.println( data + " will be added to the front!");
Node nn = new Node(data);
nn.next = head;
nn.prev = null;
if (head != null) head.prev = nn;
head = nn;
if (tail == null) tail = nn;
}
public void addToBack(int data){
Node nn = new Node(data);
System.out.println(data + " will be added to the back!");
if (tail != null) tail.next = nn;
tail = nn;
if (head == null) head = nn;
}
public void printForward(){
System.out.println("Printing forward!");
Node runner = head;
while(runner != null){
System.out.println(runner.data);
runner = runner.next;
}
}
public void printBackward(){
System.out.println("Printing backwards");
Node runner = tail;
while (runner != null){
System.out.println(runner.data);
runner = runner.prev;
}
}
}
The test code is below:
public class DDLTest{
public static void main (String[] args){
DLL dl = new DLL();
dl.addToFront(2);
dl.addToFront(1);
dl.addToBack(3);
dl.printForward();
dl.printBackward();
}
}

Your addToBack method is not setting the prev pointer of the new node.
Add this:
if (tail != null) {
tail.next = nn;
nn.prev = tail;
}

you have to point back in addToback method
public void addToBack(int data){
Node nn = new Node(data);
System.out.println(data + " will be added to the back!");
if (tail != null){
tail.next = nn;
nn.prev = tail;
tail = nn;
}
if (head == null) head = nn;
}

Related

Java Double Linked List Previous [duplicate]

This question already has answers here:
Delete Last Node of a Linked List
(15 answers)
Closed 5 years ago.
I am trying to create a double linked list and am having trouble with the removeLast method.
public class Node<E> {
E data;
public Node<E> next;
public Node<E> prev;
public Node(E d)
{
data = d;
}
public E getData()
{
return data;
}
}
public class TestList<E> {
Node<E> head;
Node<E> tail;
public void addLast(E data)
{
Node<E> newData = new Node<E>(data);
if (head == null)
{
head = newData;
tail = newData;
}
else
{
Node<E> current = head;
while (current.next != null)
current = current.next;
current.next = newData;
tail = current.next;
}
}
public void removeLast()
{
if (head == null)
System.out.println("List is empty!");
else
{
Node<E> current = tail;
}
}
If for example I had a list of integers with the values 1, 3, 5 with 1 being the head and 5 being the tail, in my removeLast method I would like to know how I could make current.prev point to 3 and current.prev.prev point to 1 as right now it would just point to the next values which in this case would be null.
You have to modify both addLast() and removeLest() with check 3 different situations in both methods.
public final class TestList<E> {
private Node<E> head;
private Node<E> tail;
public void addLast(E data) {
Node<E> node = new Node<>(data);
if (head == null)
head = tail = node;
else if (head == tail) {
tail = node;
head.next = tail;
tail.prev = head;
} else {
tail.next = node;
node.prev = tail;
tail = node;
}
}
public void removeLast() {
if (tail == null)
System.err.println("List is empty!");
else if (head == tail)
head = tail = null;
else {
Node<E> prev = tail.prev;
tail.prev = null;
tail = null;
tail = prev;
tail.next = null;
}
}
private static final class Node<E> {
E data;
Node<E> next;
Node<E> prev;
public Node(E data) {
this.data = data;
}
}
}
You can do:
If the list is already empty, do nothing
Or else, if head is the same as the tail (there is only one element in list), then clear the list
Or else, make tail.prev.next point to null, and then make tail = prev
Like this:
public void removeLast() {
if (head == null) {
System.out.println("List is empty!");
return;
}
if (head == tail) {
head = tail = null;
return;
}
Node<E> prev = tail.prev;
prev.next = null;
tail = prev;
}

Pass by value Linked list

I am trying to rearrange a Singly linked list. The initial list will be 1,2,3,4,5
and they have to be sorted in 1,5,2,4,3. I have the code and I am trying to understand how it works. Basically I am stuck at the concept of pass by value in java.
The complete code
public class Test {
public static void main(String[] args) {
LinkedLists linkedList = new LinkedLists();
linkedList.append(1);
linkedList.append(2);
linkedList.append(3);
linkedList.append(4);
linkedList.append(5);
linkedList.reorderList();
}}
class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
}}
class LinkedLists {
Node head;
public void reorderList() {
if (head == null) {
System.out.println(head);
return;
}
Node slowPointer = head;
Node fastPointer = head.next;
System.out.println(slowPointer.hashCode());
System.out.println(head.hashCode());
while (fastPointer != null && fastPointer.next != null) {
fastPointer = fastPointer.next.next;
slowPointer = slowPointer.next;// why head value did not change
}
Node head2 = slowPointer.next;
slowPointer.next = null;// why did the head value change here
LinkedList<Node> queue = new LinkedList<Node>();
while (head2 != null) {
Node temp = head2;
head2 = head2.next;
temp.next = null;
queue.push(temp);
}
while (!queue.isEmpty()) {
Node temp = queue.pop();
temp.next = head.next;
head.next = temp;
head = temp.next;
}
}
public void append(int data) {
if (head == null) {
head = new Node(data);
return;
}
Node current = head;
while (current.next != null) {
current = current.next;
}
current.next = new Node(data);
}}
The value of head does not get changed at line
slowPointer = slowPointer.next;// why head value did not change
But at line
slowPointer.next = null;// why did the head value change here
Why does it change here. Thanks.
Because in the first case you are assigning the object pointed by next to the slowPointer.
But in second case you are modifying the value of 'next' of the object being pointed by the reference slowPointer. So the head object is directly modified.

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);
}
}
}

Adding at the End

Thank you for taking the time to read this, I'm currently taking a Java class and the professor told us that a good practice to understand links would be to make a doubly linked list. I have made a singly linked list but I am having trouble converting it to a doubly linked list. The problem I am having is I'm trying to add a number to the end of the list but when I try to add a new number to the end it just shows that numbers and not the others. I think I'm just creating a new list and displaying that but I'm not sure. An example of code would be really appreciated.
Normal Add Code:
public void add(int element){
Node n = new Node();
n.setItem(element);
n.setNext(head);
n.setBefore(null);
if(head != null) {
head.setBefore(n);
}
head = n;
}
The add to last code:
public void addLast(int element) {
Node currentNode = head;
currentNode.setItem(element);
currentNode.setBefore(tail);
currentNode.setNext(null);
tail = currentNode;
}
FULL CODE:
public class DoubleLink {
private Node head;
private Node tail;
//Methods
//Constructors
public DoubleLink(){
head = null;
tail = null;
}
public void add(int element){
Node n = new Node();
n.setItem(element);
n.setNext(head);
n.setBefore(null);
if(head != null) {
head.setBefore(n);
head = n;
}
public void display(){ //LIST TRAVERSAL!
// Reference traversal
//Needed an interatior
Node currentNode = head;
while(currentNode != null){
System.out.print(currentNode.getItem()+ " ");
currentNode = currentNode.getNext();
}
System.out.println();
}
public int search(int element){
int position = 0;
Node currentNode = head;
while(currentNode != null){
if(currentNode.getItem() == element){
return position;
}
position++;
currentNode = currentNode.getNext();
}
return -1;
}
public void insert(int element, int position){
int currentposition = 0;
Node currentNode = head;
//Traverse to the right position
while(currentposition < position-1){
currentposition++;
}
Node n = new Node();
n.setItem(element);
n.setNext(currentNode.getNext());
currentNode.setNext(n);
//The previous number connecting to the new number
currentNode = tail;
}
public void remove(int position){
int currentposition = 0;
Node currentNode = head;
//Traverse to the right position
while(currentposition < position-1){
currentposition++;
}
Node dyingNode = currentNode.getNext();
currentNode.setNext(dyingNode.getNext());
}
public void addLast(int element) {
Node nodeToInsert = new Node();
nodeToInsert.setItem(element);
nodeToInsert.setBefore(tail);
nodeToInsert.setNext(null);
if(tail != null)
tail.setNext(nodeToInsert); //link the list
tail = nodeToInsert; //now the tail is the new node i added
if(head == null) // if the list has no elements then set the head
head = nodeToInsert;
}
public static void main(String[] args) {
DoubleLink l = new DoubleLink();
l.add(1);
l.add(2);
l.add(3);
l.display();
l.addLast(99);
l.display();
}
}
Node Class:
public class Node {
//Data
private int item;
private Node next;
private Node before;
//Methods
public int getItem(){
return item;
}
public void setItem(int item){
this.item = item;
}
public Node getNext(){
return next;
}
public void setNext (Node next){
this.next = next;
}
public Node getBefore(){
return before;
}
public void setBefore(Node before){
this.before = before;
}
}
You should change your code, creating a new Node() like this.
public void addLast(int element) {
Node nodeToInsert = new Node();
nodeToInsert.setItem(element);
nodeToInsert.setBefore(tail);
nodeToInsert.setNext(null);
if(tail != null)
tail.setNext(nodeToInsert); //link the list
tail = nodeToInsert; //now the tail is the new node i added
if(head == null) // if the list has no elements then set the head
head = nodeToInsert;
}
UPDATE
The problem is in your add method , you are not setting never tail
public void add(int element){
Node n = new Node();
n.setItem(element);
n.setNext(head);
n.setBefore(null);
if(head != null)
head.setBefore(n);
else{
tail=n; // if head == null then now you have an element so head = tail
}
head = n;
}
Try this :
public void addLast(int element) {
Node newNode = new Node();
newNode.setItem(element);
newNode.setNext(null);
newNode.setBefore(tail);
tail.setNext(newNode);
tail = newNode;
}
In addlast(int element) you are not creating memory for new node you just overwriting in the
head node.
So, your code goes like this
public void addlist(int element)
{
Node currentNode = new node();
currentNode.setItem(element);
currentNode.setBefore(tail);
currentNode.setNext(null);
if(tail!=null)
tail.setNext(currentNode);
tail = currentNode;
}

Adding items to end of linked list

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;
}
}

Categories