Linked List using java which has insertion command - java

I created a linked list insertion program where i want to insert node when pressed 1 and exit when 0 is pressed but only first node i.e the head is being inserted not other nodes....
It seems like the first node is working fine but the other nodes are not inserted ..
Please help to identify where the problem lies.
import java.util.*;
// A simple Java program for traversal of a linked list
public class LinkedList {
Node head; // head of list which is object of Inner Node Class.. thus head.data is a valid statement..
/* Linked list Node. This inner class is made static so that
main() can access it */
static class Node {
int data;
Node next;
//Constructor
Node(int d)
{
data = d;
next = null;
} // Constructor
}
/* This function prints contents of linked list starting from head */
public void printList()
{
Node n = head;
while (n != null) {
System.out.print(n.data + " ");
n = n.next;
}
}
/* method to create a simple linked list with 3 nodes*/
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int dt=0;
/* Start with the empty list. */
LinkedList llist = new LinkedList();
System.out.println("Enter 1 for entry 0 for exit");
int p = sc.nextInt();
while(p!=0)
{
if(llist.head==null)
{
System.out.println("Enter the first data in linked list");
dt=sc.nextInt();
llist.head = new Node(dt);
llist.head.next=null;
}
else //problem is here//
{ Node n=llist.head.next;
System.out.println("Enter the data in linked list");
dt=sc.nextInt();
while (n != null)
{
Node nd = new Node(dt);
nd.next = null;
}
}
System.out.println("Enter 1 for entry 0 for exit");
p = sc.nextInt();
}
llist.printList();
}
}

In the while loop, you can keep looping while n.next is not null. This means that you will exit the loop when n.next is null, i.e. you reached the end of the list.
The else branch could be written like this:
LinkedList.Node n=llist.head;
System.out.println("Enter the data in linked list");
dt=sc.nextInt();
while (n.next != null)
{
n = n.next;
}
// if we reach here, n.next must be null, i.e. we have reached the end of the list
n.next = new LinkedList.Node(dt);
Alternatively, you could store the last node that was inserted in a variable. This way you don't need to find the end of the list every time.
LinkedList.Node tail = null;
while(p!=0)
{
if(llist.head==null)
{
System.out.println("Enter the first data in linked list");
dt=sc.nextInt();
llist.head = new LinkedList.Node(dt);
llist.head.next=null;
tail = llist.head;
} else {
System.out.println("Enter the data in linked list");
dt=sc.nextInt();
tail.next = new LinkedList.Node(dt);
tail = tail.next;
}
System.out.println("Enter 1 for entry 0 for exit");
p = sc.nextInt();
}
An even better way to do this would be to add an insert method to LinkedList:
public void insert(int data) {
if (head == null) {
head = new Node(data);
} else {
LinkedList.Node n = head;
while (n.next != null) {
n = n.next;
}
n.next = new Node(data);
}
}
Then the outer while loop can become:
while(p!=0)
{
System.out.println("Enter the data in linked list");
dt=sc.nextInt();
llist.insert(dt);
System.out.println("Enter 1 for entry 0 for exit");
p = sc.nextInt();
}

Related

Printing a circular singly linked List

Below is my code to print a circular singly linked list from the SECOND NODE(i.e. the node next to my starting node from where I have inserted my values). But it seems that my code is unable to link the last node to my starting node. As a result of which I am not able to print my Circular linked list.
Can somebody correct my mistake?
INPUT: 1 2 3 4
EXPECTED O/P: 2 3 4 1
O/P GETTING: 2 3 4
import java.util.Scanner;
public class CircularLinkedList {
CircularLinkedList ptr,head,next;
int v;
void headcre()
{
head=new CircularLinkedList();
ptr=head;
}
void linkcre(int n)
{
Scanner sc=new Scanner(System.in);
ptr=head;
System.out.println("Enter elements of list");
for(int i=0;i<n;i++)
{
ptr.v=sc.nextInt();
ptr.next=new CircularLinkedList();
ptr=ptr.next;
}
ptr.next=head; //TO LINK LAST NODE TO STARTING NODE
}
void printcre()
{
ptr=head;
ptr=ptr.next; //printing the list from the second node
while(ptr.next!=head)
{
System.out.print(ptr.v+" ");
ptr=ptr.next;
}
}
public static void main(String[] args) {
CircularLinkedList obj=new CircularLinkedList();
System.out.println("Enter number of elements to be present in the list");
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
obj.headcre(); //To create starting node
obj.linkcre(n); //To enter elements
obj.printcre(); //To print the list
}
}
Some issues:
Your code is trying to fit two different concepts into one class: a node of a list, and the list itself. It is weird that a first instance of the CircularLinkedList class serves as the container for head, while other instances (which also have a head reference which remains useless) serve as the actual data-nodes of the list. You should dedicate a separate class for each.
The code creates a node before it has a value to store in that node. This means your list will always have a node that is unused for data. So when all input has been stored in nodes, there is one more node that was created, which has no data (ptr.v remains uninitialised).
In printcre, when the head node is visited, the loop exits, and so that node's value is never printed.
It is not good practice to perform I/O in methods of such a class. Keep I/O in your main code, and provided methods that do the pure list stuff, or maybe produce a string representation of the list. But don't do I/O in these methods. Mixing concerns like that is not a good habit.
For a circular list it is actually more interesting to keep a reference to the tail than to the head, because the head can be easily be found from the tail (it is its successor), while getting the tail from the head requires to traverse all nodes.
Here is code I would suggest:
ListNode class
public class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
this.next = this; // Make circular by default
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
CircularLinkedList class
public class CircularLinkedList {
ListNode tail = null;
public void append(int data) {
if (tail == null) {
tail = new ListNode(data);
} else {
tail = tail.next = new ListNode(data, tail.next);
}
}
public String toString() {
if (tail == null) return "";
String s = "";
ListNode node = tail.next.next;
while (node != tail.next) {
s += node.val + " ";
node = node.next;
}
return s + node.val; // Also include the head's value in the string
}
}
Driver code
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter number of elements to be present in the list");
int n = sc.nextInt();
CircularLinkedList list = new CircularLinkedList();
System.out.println("Enter elements of list");
for (int i = 0; i < n; i++) {
list.append(sc.nextInt());
}
sc.close();
System.out.println(list.toString());
}

Inserting a node at a specific position in a Linked List, throwing out runtime error when appending elements

I am trying to take user input first on how many items he wants to add and then adding them in the reverse order(appending). Next is trying to take two inputs: adding some integer to a specific position but it is throwing runtime error. Also, is there anyway to make this code more readable or efficient?
Error:
Exception in thread "main" java.lang.NullPointerException: Cannot assign field "next" because "<local3>" is null
at Solution.append(Solution.java:37)
at Solution.main(Solution.java:79)
Input:
3
16
13
7
1
2
Expected Output: 16 13 1 7
Output: ~ no response on stdout ~
Code:
public class Solution{
Node head;
static class Node{
int data;
Node next;
Node(int d) {
this.data = d;
next = null;
}
}
public void append(int newData){
Node newNode = new Node(newData);
if(head == null){
head = new Node(newData);
return;
}
newNode.next = null;
Node last = head;
while(last != null) {
last = last.next;
}
last.next = newNode;
return;
}
public void printList(){
Node temp = head;
while(temp != null){
System.out.print(temp.data + " ");
temp = temp.next;
}
}
public void insertAt(Node head, int position, int data){
Node node = new Node(data);
if(head == null) {
head = new Node(data);
return;
}
else if(position == 0) {
node.next = head;
head = node;
return;
}
else{
Node current = head;
for( int j = 0; j < position-1; j++){
current = current.next;
}
node.next = current.next;
current.next = node;
return;
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
Solution llist = new Solution();
int n = sc.nextInt(); sc.nextLine();
for( int i = 0; i < n; i++) {
int element = sc.nextInt();
if(sc.hasNextLine()) sc.nextLine();
llist.append(element);
}
int data = sc.nextInt(); sc.nextLine();
int position = sc.nextInt(); sc.nextLine();
llist.insertAt(llist.head, position, data);
llist.printList();
}
}
I dont fully understand what you are trying to do. But I would sugget to you maybe to do some priting at your main so you can follow the input from the user. From the errors kind I can guess that maybe the user enter some data to the node and some where at your code the program treats this variable as an index
So at first just make your main something like that:
Scanner sc = new Scanner(System.in);
Solution llist = new Solution();
System.out.println("How many items");
int n=sc.nextInt();
for( int i = 0; i < n; i++) {
System.out.println("Enter the element");
int element = sc.nextInt();
System.out.println("Enter the index");
int index=sc.nextInt();
llist.append(element);
}
and keep going with the rest of your code
Exception message points to the problem:
Node last = head;
while(last != null) { // loop ends when last == null
last = last.next;
}
last.next = newNode; // accessing property of a null object -> NPE
While loop most probably should be:
while(last.next != null)

Linked List Deletion

What's wrong in the below delete method logic? Why am I not getting correct output After Deletion.
import java.util.Scanner;
//Node Class
class Node1 {
int data;
Node1 Next;
Node1(int data) {
this.data = data;
Next = null;
}
}
//Main Class
public class LinkedListInsert {
//Inserting node in LinkedList
public static Node1 insert(Node1 head, int data) {
Node1 p = new Node1(data);
if (head == null)
head = p;
else {
Node1 start = head;
while (start.Next != null)
start = start.Next;
start.Next = p;
}
return head;
}
//Deleting node from LinkedList
public static Node1 delete(Node1 head, int d) {
Node1 start = head;
while (start.data != d) {
start = start.Next;
}
while (start.Next != null) {
start.data = start.Next.data;
start = start.Next;
}
start = null;
return head;
}
//Displaying Linked List
public static void display(Node1 head) {
Node1 start = head;
while (start != null) {
System.out.print(start.data + " ");
start = start.Next;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n;
Node1 head = null;
System.out.println("Enter the numbers of node to be inserted");
n = sc.nextInt();
while (n--> 0) {
System.out.println("enter node");
head = insert(head, sc.nextInt());
}
System.out.println("Before Deletion");
display(head);
delete(head, 3);//I have hard coded the deleting node as 3
System.out.println();
System.out.println("After Deletion");
display(head);
}
}
Input: 6 2 3 1 8
Node to be deleted: 3
Output:
Before Deletion
6 2 3 1 8
After Deletion
6 2 1 8 8
As you can see node 3 is deleted from the list but 8 is coming for 2 times.
//I have hard coded the deleting node as 3
Because there is a bug in delete(), you didn't delete any node actually, you only changed the value of the node you want to delete and all nodes' value to next node's. Here is a modified code, you can use delete2() to test:
//Deleting node from LinkedList
public static Node1 delete2(Node1 head, int d) {
if (head.data == d) {
// Delete head node
return head.Next;
}
Node1 start = head;
while (start.Next != null) {
if (start.Next.data == d) {
// Delete the next node
start.Next = start.Next.Next;
break;
}
start = start.Next;
}
return head;
}
public static Node1 delete(Node1 head, int d) {
Node1 start = head;
while (start.data != d) {
start = start.Next;
}
while (start.Next != null) {
start.data = start.Next.data;
start = start.Next;
}
start = null;
return head;
}
can you use the below code display the values of linked list.
public void display(){
LinkedNode currNode =head;
while(true){
if(currNode == null){
break;
}
System.out.println("Iterating a LinkedList=-=-=-=>"+currNode.val);
currNode = currNode.nxt;
}
}
Please format the source code properly.
I was just going through the code you have provided. Here it looks like before deletion you are inserting node first and then you are deleting. Definitely the list also will show you what you have added through the insertion when it asks "enter node".
Please verify the same.
I just tried the same. Once I give input of
6 2 3 1 8
Then it asks to enter node and I added 9
Again I added 0
Then I got the below output:
Before Deletion
2 3 1 8 9 0
After Deletion
2 1 8 9 0 0
Hence it deleted 6 from LinkedList.

Java - Counting Occurrences in a Linked List

As part of an assignment, I have to write a method that will print out repeating values in a linked list, as well as how many times they occur. Below is the method printRepeats() which uses the helper method countRepeats(ListNode node).
The issue is that the output of my method prints repeating values over and over again. For example, in a list with values 1 1 1 2 3 4 5 6 7 6, the output is 1 (Occurences = 3) 1 (Occurences = 3) 1 (Occurences = 3) 6 (Occurences = 2) 6 (Occurences = 2). Any value that repeats should only print once. Any suggestions? Thanks in advance!
public class LinkedList
{
private ListNode first;
public void printRepeats()
{
String ans = "";
ListNode temp = first;
while(temp != null)
{
if(countRepeats(temp) > 1 && ans.indexOf((int)temp.getValue()) == -1)
{
ans += temp.getValue();
System.out.print(temp.getValue() + " (Occurences = " + countRepeats(temp) + ") ");
}
temp = temp.getNext();
}
if(ans.length() == 0)
System.out.print("None of the elements repeat.");
}
private int countRepeats(ListNode node)
{
ListNode temp = first;
int count = 0;
while(temp != null)
{
if((int)temp.getValue() == (int)node.getValue())
count++;
temp = temp.getNext();
}
return count;
}
}
Considering that you must not use any other data structures than a LinkedList, you could:
Create another ListNode element as the first element of a list called "repeatedElements", that must contain pairs element/repetitions of such element.
When counting the repetitions of a single element, insert the element and the number of repetitions it has in "repeatedElements" list.
Before counting the number of repetitions of an element, sweep the repeatedElements list for the element. If the element is present, DO NOT print the output. If it is not, repeat your code as usual.
The system I described will contain more information than the specifically required (the number of repetitions of each element is stored), but it is likely that it will be needed again.
For counting occurrences you need to maintain track record of visited node also like if you have already count any node then need not to pick again those come on link list. Below program clearly explains this-
import java.util.ArrayList;
public class CustomLinkList {
public static void main(String[] args) {
ListNode linkedList = new ListNode(15);
linkedList.next =new ListNode(67);
linkedList.next.next =new ListNode(15);
linkedList.next.next.next =new ListNode(65);
linkedList.next.next.next.next =new ListNode(13);
linkedList.next.next.next.next.next =new ListNode(98);
linkedList.next.next.next.next.next.next =new ListNode(33);
linkedList.next.next.next.next.next.next.next =new ListNode(29);
linkedList.next.next.next.next.next.next.next.next =new ListNode(15);
ListNode printList = linkedList;
System.out.println("Custom Link List is ::: ");
while (printList.next != null){
System.out.printf("%d ",printList.info);
printList = printList.next;
}
System.out.println();
CustomLinkList.occurancesOfElement(linkedList);
}
public static void occurancesOfElement(ListNode listNode){
ArrayList<Integer> visitedNode = new ArrayList();
while(listNode !=null){
ListNode node = listNode;
int count = 0;
while (node !=null)
{
if(listNode.info == node.info && !visitedNode.contains(node.info)) {
count++;
}
node = node.next;
}
if(!visitedNode.contains(listNode.info))
System.out.println("Occurences of : "+listNode.info+" is "+ count);
visitedNode.add(listNode.info);
listNode = listNode.next;
}
}
}
class ListNode {
int info;
ListNode next;
ListNode(int info){
this.info = info;
next = null;
}
}
class DoublyListNode {
int info;
DoublyListNode previous;
DoublyListNode next;
}
}

Append two linked list

I wrote a simple method to append a linked list at the end of another linked list.So what the program should ideally do is when I give it two lists
list1 ===>1->2->3
list2 ===>4->5->6
updatedList ==>1->2->3->4->5->6
But when I run the method appendList it goes into an infinite loop printing 1 to 6 indefinitely.What am I doing wrong out here?
public static Node appendList(Node head1, Node head2) {
Node prev = null;
Node current = head1;
while (current != null) {
prev = current;
current = current.next;
}
prev.next = head2;
return head1;
}
Oh and I forgot to add the Node class and how I call the method from my main .I know its bit cumbersome but here it is
public class ReverseLinkedList {
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
}
public void displayData() {
System.out.println(data);
}
}
public static void main(String args[]) {
ReverseLinkedList reversedList = new ReverseLinkedList();
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the length of the linked list!!");
int listSize = scanner.nextInt();
System.out.println("Enter the Numbers you want to insert!!");
int count = 0;
while (scanner.hasNextLine()) {
if (count == listSize)
break;
reversedList.insert(scanner.nextInt());
count++;
}
System.out.println("Inserted List !!");
reversedList.displayList();
/*
* Node reverseNodeStart =
* reversedList.reverseList1(reversedList.first);
* System.out.println("Reversed List !!"); while (reverseNodeStart !=
* null) { reverseNodeStart.displayData(); reverseNodeStart =
* reverseNodeStart.next; }
*/
Node reverseNodeStart = reversedList.appendList(reversedList.first,
reversedList.first);
while (reverseNodeStart != null) {
reverseNodeStart.displayData();
reverseNodeStart = reverseNodeStart.next;
}
}
}
The problem was I was using the same List which was causing the circular reference.It works fine now.You knew the problem even before I posted the code now that's impressive. Thanks!!I solved it by creating a new List2 and passing in List1 and List2.
appendList(Node lis1head, Node list2head)

Categories

Resources