Generic Doubly Linked List Implementation - java

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.

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

How to reverse a LinkedList from a certain index, given the code fragments below

I would like to write a method public void reverseFrom(int index) which reverses a list from the given index.
I would like to only use the LinkedList class below.
public class LinkedList {
public Node head = null;
public class Node {
public int value;
public Node next;
Node(int value, Node next) {
this.value = value
this.next = next;
}
}
}
I have a method to reverse a LinkedList:
public void reverse() {
Node tmp = head;
Node prev = null;
Node nextNode = null;
while(tmp != null) {
nextNode = tmp.next;
tmp.next = prev;
prev = tmp;
tmp = nextNode;
}
head = prev;
}
So far, for the reverseFrom method, I have:
public void reverseFrom(int index) {
if(index == 0) {
reverse();
} else if (index == 1) {
return;
} else {
Node tmp = head;
for(int i = 0; i < index; i++) {
tmp = tmp.next;
}
Node newHead = tmp;
/*** Node prev = null;
Node nextNode = null;
while(newHead != null) {
nextNode = newHead.next;
newHead.next = prev;
prev = newHead;
newHead = nextNode;
}
newHead = prev; ***/
}
}
I have tried using the code from reverse() but it does not work (that which is commented out).
How can I then reverse the list from newHead?
You could base the logic on the reverse method, but use an extra reference to the node that is at index - 1. During the loop decrement index. As long as it is positive, don't change the next reference of the current node. When it hits zero, take note of where we start the reversal, and as the current node will become the very last one, set its next reference to null. When index is negative, perform the usual reversal logic.
After the loop, check whether we need to change the head or whether we need to attach the reversed part to the node at index-1:
public void reverseFrom(int index) {
Node tmp = head;
Node prev = null;
Node nextNode = null;
Node tail = null; // node at index - 1
while (tmp != null) {
nextNode = tmp.next;
if (index == 0) {
// We arrived at the part that needs reversal
tmp.next = null;
tail = prev;
} else if (index < 0) {
// Perform normal reversal logic
tmp.next = prev;
}
index--;
prev = tmp;
tmp = nextNode;
}
if (tail == null) {
head = prev;
} else {
tail.next = prev;
}
}
public class ReverseList<T> extends LinkedList<T>{
public void reverseFrom(int idx) {
if (idx < 0 || idx > size()) {
return;
}
Stack<T> stack = new Stack<T>();
while (idx < size()) {
stack.push(remove(idx));
}
while (!stack.isEmpty()) {
add(stack.pop());
}
}
/******* Alternative slution ***************/
public void reverseFrom(int idx) {
if (idx < 0 || idx > size()) {
return;
}
reverseFromInternal(idx, size()-1);
}
private void reverseFromInternal(int a, int b) {
if (a >= b) {
return;
}
T far = remove(b);
T near = remove(a);
add(a, far);
add(b, near);
reverseFromInternal(a + 1, b - 1);
}
/****************************************/
public static void main(String [] args) {
ReverseList<String> list = new ReverseList<>();
for (int i = 0; i < 10; i++) {
list.add(Integer.toString(i));
}
list.reverseFrom(5);
System.out.println(list);
}
}
public void reverseFrom(int index) {
if (index == 0) {
reverse();
return;
}
Node tmp = head;
Node previous = null;
for (int i = 0; i < index; i++) {
previous = tmp;
tmp = tmp.next;
}
Node newHead = tmp;
LinkedList subLinkedList = new LinkedList();
subLinkedList.head = newHead;
subLinkedList.reverse();
previous.next = subLinkedList.head;
}

How can I delete any node at random out of a Doubly Linked List in Java?

I'm making a Doubly Linked List that allows you to insert at the front and rear, as well as deleting any node from the list as long as it exists. The problem is that it doesn't work and gives off and either gives off a NullPointerException or it just says That Integer does not exist even though it does exist.The code is:
public class Numbers {
Node head = null; //Head of the list
Node tail = null; //end of the doubly list
int size = 0;
public void FrontInsert(int data) {
Node n = new Node();
if (head == null) {
head = n;
} else {
n.prev = head;
head.next = n;
head = n;
}
size++;
}
public void RearInsert(int data) {
Node n = new Node();
if (head == null) {
head = n;
tail = n;
} else {
n.next = tail;
tail.prev = n;
tail = n;
}
size++;
}
public void Delete(int x) {
if (size == 0) {
System.out.println("The list is empty.");
}
if (head.data == x) {
head = head.next;
if (head != null) {
head.prev = null;
}
size--;
return;
}
tmp = head;
while (tmp != null && tmp.data != x) {
tmp = tmp.next;
}
if (tmp == null) {
System.out.println("That integer does not exist.");
return;
}
if (tmp.data == x) {
tmp.prev.next = tmp.next;
if (tmp.next != null) {
tmp.next.prev = tmp.prev;
}
}
size--;
}
public void printList() {
while (head != null) {
System.out.print(head.data + " ");
head = head.prev;
}
}
public static void main(String[] args) {
Numbers nu = new Numbers();
}
class Node {
Node prev;
Node next;
int data;
public void Node(int data) {
this.data = data;
next = null;
prev = null;
}
}
}
Try this and check output
public class Numbers {
Node head = null;
Node tail = null;
int size = 0;
public void FrontInsert(int data) {
Node n = new Node(data);
if (head == null) { // first insert
head = n;
tail = n;
} else {
n.next = head;
head.prev = n;
head = n;
}
size++;
}
public void RearInsert(int data) {
Node n = new Node(data);
if (head == null) {
head = n;
tail = n;
} else {
n.prev = tail;
tail.next = n;
tail = n;
}
size++;
}
public void Delete(int index) { // index is the position to be remove
if (size == 0) {
System.out.println("The list is empty."); return;
}else if(index < 0 || index > size -1){
System.out.println("Index outOf Bound."); return;
}
Node currentNode = head;
for(int i = 1; i <= index ; i++){
currentNode = currentNode.next;
}
//remove
if (index == 0) {
currentNode.next.prev = null;
head = currentNode.next;
} else if (index == size - 1) {
currentNode.prev.next = null;
tail = currentNode.prev;
} else {
if (currentNode.prev != null) // Ensure its not header
currentNode.prev.next = currentNode.next;
if (currentNode.next != null) // Ensure its not tail
currentNode.next.prev = currentNode.prev;
}
size--;
}
public void printList() {
Node tmp = head;
while (tmp != null) {
System.out.print(tmp.data + " ");
tmp = tmp.next;
}
System.out.println();
}
public static void main(String[] args) {
Numbers nu = new Numbers();
nu.FrontInsert(1);nu.printList();
nu.FrontInsert(2);nu.printList();
nu.RearInsert(3);nu.printList();
nu.FrontInsert(4);nu.printList();
nu.RearInsert(3);nu.printList();
nu.FrontInsert(4);nu.printList();
nu.RearInsert(3);nu.printList();
nu.RearInsert(3);nu.printList();
nu.FrontInsert(4);nu.printList();
System.out.println();
nu.Delete(4);
nu.printList();
}
class Node {
Node prev;
Node next;
int data;
public Node(int data) {
this.data = data;
next = null;
prev = null;
}
}
}
Well, your head and tail were mutually exclusive, i mean when you add something to the tail of the list, you were only giving one side reference not both side, you have to says
tail.next = n; n.prev = tail; and tail = n.
Here is a working code:
public class Numbers {
Node head = null; //Head of the list
Node tail = null; //end of the doubly list
int size = 0;
public void FrontInsert(int data) {
Node n = new Node(data);
if (head == null) {
head = n;
tail = head;
} else {
n.next = head;
head.prev = n;
head = n;
}
size++;
}
public void RearInsert(int data) {
Node n = new Node(data);
if (head == null) {
head = n;
tail = head;
} else {
n.next = null;
tail.next = n;
n.prev = tail;
tail = n;
}
size++;
}
#SuppressWarnings("null")
public void Delete(int x) {
if (size == 0) {
System.out.println("The list is empty.");
return;
}
if (head.data == x) {
head = head.next;
if (head != null) {
head.prev = null;
}
size--;
return;
}
Node tmp = head;
while (true) {
if(tmp == null)
break;
if(tmp.data == x)
break;
System.out.println(tmp.data);
tmp = tmp.next;
}
if (tmp == null) {
System.out.println("That integer does not exist.");
return;
}
if (tmp.data == x) {
tmp.prev.next = tmp.next;
if (tmp.next != null) {
tmp.next.prev = tmp.prev;
}
}
size--;
}
public void printList() {
while (head != null) {
System.out.print(head.data + " ");
head = head.next;
}
}
public static void main(String[] args) {
Numbers nu = new Numbers();
nu.FrontInsert(2);
nu.FrontInsert(3);
nu.FrontInsert(6);
nu.RearInsert(8);
nu.RearInsert(20);
nu.Delete(8);
nu.printList();
// System.out.println(nu.head.data + "data");
// System.out.println(nu.head.next.data + "data");
}
class Node {
Node prev;
Node next;
private int data;
public Node(int data) {
this.data = data;
next = null;
prev = null;
}
}
}

Linked List Reversal

My code for linked list reversal doesn't compile. Everything seems to be logically correct.
Here is the snippet of my LinkedList class:
public class LinkedList {
Node head;
public static class Node {
int data;
Node next;
Node(int d) {
this.data = d;
this.next = null;
}
}
public void display(Node n) {
n = head;
int ctr;
while (n != null) {
System.out.print(n.data +" ");
n = n.next;
}
ctr = countNodes(head);
System.out.println("The list length is "+ctr);
}
public Node recreverse(Node n){
Node prev = null;
Node temp = null;
if (n.next == null) {
head = n;
head.next = prev;
return head;
} else {
temp = n;
n = n.next;
prev = n;
prev.next = temp;
return n;
}
}
}
countNodes(Node) is not defined anywhere:
ctr = countNodes(head);
Define it and the code will compile.

Remove all nodes with a given value using 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).

Categories