Printing a circular singly linked List - java

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

Related

Linked List using java which has insertion command

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

Making a Linked List in Java

I am adding elements in a Linked List via scanning the elements one by one using a for loop, but at the end there is a 0 coming while printing the list. The last node is pointing to null but still the list is having one element that is 0. I am providing my source code below and then inputs
import java.util.Scanner;
import static java.lang.System.out;
class Node{
int data;
Node next;
Node(){
this.next=null;
}
Node(int data){
this.data=data;
this.next=null;
}
}
public class MyClass{
public static void main(String args[]) {
Node head=new Node();
Node temp=head;
Scanner sc = new Scanner(System.in);
int size=sc.nextInt();
for(int i=1;i<=size;i++){
temp.data=sc.nextInt();
temp.next=new Node();
temp=temp.next;
}
temp=null;
while(head!=null){
out.print(head.data+" ");
head=head.next;
}
}
}
Inputs:
5 1 2 3 4 5
The next pointer in the last node of a linked list should be null to denote that it is the last node.
In your case, you are keeping it 'not null'. In your for loop, just don't instantiate the next pointer if it is the last element you are reading.
for(int i=1;i<=size;i++){
temp.data=sc.nextInt();
if(i != size) {
temp.next=new Node();
temp=temp.next;
}
}
The problem is that even though you are setting temp=null after you exit your loop, you still have one extra unassigned node.
The simplest fix is to remove the '=' sign in your for loop so that you exit the loop after your last node and then assign your final value, like this:
for(int i=1;i<size;i++){
temp.data=sc.nextInt();
temp.next=new Node();
temp=temp.next;
}
temp.data=sc.nextInt();
You're creating the head-node outside of the loop and a new node within it.
You therefore get 1 extra node.
You might try the following:
public static void main(String args[]) {
Node head=null;
Node last=null;
Scanner sc = new Scanner(System.in);
int size=sc.nextInt();
for(int i=1;i<=size;i++){
if (head == null){
head = new Node();
last = head;
} else {
last.next = new Node();
last = last.next();
}
last.data=sc.nextInt();
}
while(head!=null){
out.print(head.data+" ");
head=head.next;
}
}

Java Priority Queue in Linked List Test Cases

So I'm trying to implement a priority queue with a linked list. I think I have the basics together, but for some reason my test cases aren't working. When I run it, the size show up fine, but none of the node values are showing (only an arrow "->" pops up once). If anyone could help me figure out why it isn't working, or suggest a better way to set up test cases in java (I've never done that before) it would be appreciated!
Node class:
public class Node { //Node class structure
int data; //data contained in Node; for assignment purposes, data is an int
Node next; //pointer to Next Node
//Node Constructor
public Node(int data) {
this.data = data;
next = null;
}
//Set Methods
public void setData(int data) { //set Node value
this.data = data;
}
public void setNext(Node next) { //set next Node value
this.next = next;
}
//Get Methods
public int getData() { //get Node value
return this.data;
}
public Node getNext() { //get next Node value
return this.next;
}
//Display the Node Value
public void displayNode() {
System.out.println(data + "urgh"); //display value as a string
}
}
Linked List Class:
import Question1.Node;
//basic set-up of a FIFO singly linked list
public class SLList{
protected Node head; //head of SLList
protected Node tail; //tail of SLList
int n; //number of elements in SLList
//SLList constructor
public SLList() {
head = null;
n = 0;
}
//check if list is empty
public boolean isEmpty() {
return head == null;
}
//return the size of the list
public int size() {
return n;
}
//add a new node to the end of the list
public boolean insert(int x){
Node y = new Node(x);
if (head == null){ //if head is null, thus an empty list
head = y; //assign head as y
}
else{ //if there is already a tail node
tail.next = y; //assign the tail's pointer to the new node
}
tail = y; //assign tail to y
this.n++; //increment the queue's size
return true; //show action has taken place
}
//remove and return node from head of list
public Node remove(){
if (n == 0){ //if the list is of size 0, and thus empty
return null; //do nothing
}
else{ //if there are node(s) in the list
Node pointer = head; //assign pointer to the head
head = head.next; //reassign head as next node,
n--; //decrement list size
return pointer; //return the pointer
}
}
//display SLList as string
public void displayList() {
Node pointer = head;
while (pointer != null) {
pointer.displayNode();
pointer = pointer.next;
}
System.out.println(" ");
}
}
Priority Queue Class:
import Question1.Node;
import Question1.SLList;
public class PriorityQueue extends SLList {
private SLList list; //SLList variable
public PriorityQueue(){ //create the official SLList
list = new SLList();
}
//add a new node; new add method that ensures the first element is sorted to be the "priority"
public boolean add(int x){
Node y = new Node(x);
if (n == 0){ //if there are 0 elements, thus an empty list
head = y; //assign head as y
}
else if (y.data < head.data){ //if new node y is the smallest element, thus highest priority
y.next = head; //assign y's next to be current head of queue
head = y; //reassign head to be actual new head of queue (y)
}
else{ //if there is already a tail node
tail.next = y; //assign the tail's pointer to the new node
}
tail = y; //assign tail to y
n++; //increment the queue's size
return true; //show action has taken place
}
//delete the minimim value (highest priority value) from the queue and return its value
public Node deleteMin(){
return list.remove(); //the list is sorted such that the element being removed in indeed the min
}
//return the size of the queue
public int size() {
return n;
}
//display Queue as string
public void displayQueue() {
System.out.println("->");
list.displayList();
}
}
Test Cases (so far, the delete one wasn't working so it's commented out):
import Question1.PriorityQueue;
public class TestQ1 { //Test code
public static void main(String[] args){
PriorityQueue PQueue1 = new PriorityQueue();
PQueue1.add(3);
PQueue1.add(2);
PQueue1.add(8);
PQueue1.add(4);
System.out.println("Test add(x): ");
PQueue1.displayQueue();
System.out.println("Test size(): " + PQueue1.size());
PriorityQueue PQueue2 = new PriorityQueue();
//Node node1 = PQueue1.deleteMin();
System.out.println("Test deleteMin():");
PQueue2.displayQueue();
System.out.println("Test size(): " + PQueue2.size());
}
}
Change list.displayList() to displayList(), and you'll see the expected output.
Why? Because your queue is already a list (that is, an instance of SLList). When a class A extends another class B, an instance of A is also an instance of B. This is inheritance.
You've also included an instance variable private SLList list within your PriorityQueue implementation, which is an example of composition. Generally you'll only do one or the other of these two options, depending on your situation. In this case it seems you're trying to use inheritance, so there's no reason to create a separate list instance variable. You're adding the data directly to the queue (using the fact that, intrinsically, it is a list in its own right).
You should remove the list instance variable, and all the usages of it should refer to the parent class' methods or variables.

How to take console input using scanner in Singly / Doubly Linked List in Java (without Collection)?

I want to solve some linked list questions but i am not able to take input from console, I don't know where I am doing wrong.
What am I doing wrong with my code :
import java.util.*;
class ScannerInputLinkedList{
static class Node{
int data;
Node next;
}
void insertNode(Node head, int data){
Node curr = head;
Node temp = new Node();
temp.data = data;
temp.next = null;
while(curr.next!=null){
curr = curr.next;
}
curr.next = temp;
System.out.print(curr.data+"->");
}
System.out.println();
public static void main(String[] args) {
ScannerInputLinkedList obj = new ScannerInputLinkedList();
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
int x;
Node head = new Node();
while(t-- > 0){
x = sc.nextInt();
obj.insertNode(head, x);
}
}
}
Just a small problem with your code. The printing statement (located above main method) is outside any method. In fact it is not needed at all. Just remove it and change System.out.print(...) to System.out.println(...) at line 19. This will make your code free of errors.
This solution was regarding your problem that you weren't able to get inputs. Apart from that, it is unclear what you are trying to achieve. In case you are trying to append nodes to your linked list, you will need to recheck your logic. Your code is creating a list with already a node, appending to it but you are printing the data of node whose next is new node.
For inputs [t = 1, x = 3], your code is printing 0->. This "0" is the data of first node for the set of inputs, and your new node will be the second node.
Anyways, just for the solution to your problem of not being able to take inputs, here is the corrected code. You can use IDE's like netbeans or eclipse to quickly identify what is wrong with your code.
import java.util.*;
class ScannerInputLinkedList{
static class Node{
int data;
Node next;
}
void insertNode(Node head, int data){
Node curr = head;
Node temp = new Node();
temp.data = data;
temp.next = null;
while(curr.next!=null){
curr = curr.next;
}
curr.next = temp;
System.out.println(curr.data+"->");
}
public static void main(String[] args) {
ScannerInputLinkedList obj = new ScannerInputLinkedList();
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
int x;
Node head = new Node();
while(t-- > 0){
x = sc.nextInt();
obj.insertNode(head, x);
}
}
}

Java Linked list adding Tail

I am learning Linked List in Java and I am trying to add numbers to the tail, say a 10 Numbers. However, after insertion I am only able to retrieve the last two numbers, I don't understand what I am doing wrong. Here is my code:
import java.util.*;
public class LinkTry
{
public static void main(String args[])
{
Scanner sx = new Scanner(System.in);
Node N = new Node();
for(int i=0;i<10;i++)
{
Node last = new Node();
while(N.link!=null)
N=N.link;
last.data = sx.nextInt();
N.link = last;
}
System.out.println("");
for(Node x=N;x!=null;x=x.link)
System.out.print("-->"+x.data);
}
public static class Node
{
int data;
Node link;
}
}
I am having a bit trouble how address is passed on here, an answer that explains the memory addressing in Linked list would be very helpful.
import java.util.Scanner;
public class LinkTry
{
public static void main(String args[])
{
Scanner sx = new Scanner(System.in);
Node first = null;
Node last = null;
for(int i=0;i<10;i++) {
Node current = new Node();
current.data = sx.nextInt();
if (first == null) {
first = current;
last = current;
} else {
last.link = current;
last = current;
}
}
System.out.println("");
for(Node x=first;x!=null;x=x.link)
System.out.print("-->"+x.data);
}
public static class Node
{
int data;
Node link;
}
}
The problem is that this line:
N=N.link;
causes N to no longer point to the head of the list, whereas this line:
for(Node x=N;x!=null;x=x.link)
assumes that N still points to the head of the list.
To fix this, you need to use separate variables — you need to keep separate references to the head of the list (for later reference) and the tail of the list (for appending elements there).
The problem is in the for loop. As you are iterating through the loop you have lost reference to the head of the List you started with i.e., Node N = new Node();
Issue in the for loop, highlighted between ** ** below
for(int i=0;i<10;i++)
{
Node last = new Node();
while(N.link!=null)
N=N.link;
last.data = sx.nextInt();
**N.link = last;**
}
At the end of 10 iterations, now 'N' is pointing to last but one Node. And so it is printing only last 2 items.

Categories

Resources