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.
Related
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());
}
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;
}
}
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);
}
}
}
My assigment is to create my own linked list class (I can't use Java's LinkedList class) and implement a selection sort on it by swapping pointers rather than data.
I've created a double-linked MyLinkedList class, but I'm having trouble with the sort method. I've tried a number of things but nothing has worked - not even anything that would make sense to post here for correction. (I do know that I need to use at least one temp Node.) It has to be a selection sort.
I'm not looking for someone to code it for me, necessarily; I'm hoping someone can help me with an algorithm that I can then turn into code myself. Any help is appreciated greatly.
Here's how I've implemented the MyLinkedList class and the associated Node class:
public class MyLinkedList
{
private Node head;
private int count;
public MyLinkedList()
{
head = new Node(null);
count = 0;
}
public void add(String line)
{
Node temp = new Node(line);
Node current = head;
while (current.getNext() != null)
{
current = current.getNext();
}
temp.setLine (line); // not sure this is how to do it
current.setNext(temp);
temp.setPrev(current);
count++;
}
public void displayList()
{
Node current = head;
for (int i = 0; i < count; i++)
{
current = current.getNext();
System.out.println(current.getLine());
}
}
public void sortList()
{
Node start = head;
Node index = start;
Node min = start;
Node temp1, temp2;
while (start.getNext() != null)
{
index = index.getNext();
if (index.getLine().compareTo(min.getLine()) < 0)
{
min = index;
}
//swap - HELP, PLEASE :-)
{
// Algorithm???
}
}
}
public int size()
{
return count;
}
private class Node
{
String textLine;
Node next;
Node prev;
public Node()
{
textLine = null;
next = null;
prev = null;
}
public Node (String line)
{
textLine = (line);
next = null;
prev = null;
}
public Node (String line, Node node1, Node node2)
{
textLine = line;
prev = node1;
next = node2;
}
public String getLine()
{
return textLine;
}
public Node getNext()
{
return next;
}
public Node getPrev()
{
return prev;
}
public void setLine(String line)
{
textLine = line;
}
public void setNext(Node nextNode)
{
next = nextNode;
}
public void setPrev(Node prevNode)
{
prev = prevNode;
}
}
}
It may get confusing if an empty MyLinked List has a node in it even if it's just one with null prev, next and data, so you need to be careful of that MyLinkedList constructor - it would probably be much easier if it read simply head = null;.
Also it would be useful if a MyLinked List had a tail node as well to save you following the chain to the end to find where add should put a new Node.
After that, I think the problem is that you haven't noticed you need two loops: one to work your way through the list to keep track of where the unsorted nodes start, and one to find the smallest node from thereon. You also need to write a swap method for Node so that you can write something like this untested pseudocode that just happens to look a lot like Java
for (index = head; index != null; index = index.getNext()) {
min = index;
for (test = min.getNext(); test != null; test = test.getNext) {
if (test.getLine().compareTo(min.getLine()) < 0)
min = test;
}
if (min != index) {
swap(index, min);
index = min;
}
}
and swap would look roughly like
public void swap(Node other)
{
Node temp;
temp = next;
next = other.getNext();
other.setNext(temp);
temp = prev;
prev = other.getPrev();
other.setPrev(temp);
other.getNext().setPrev(this);
other.getPrev().setNext(this);
this.getNext().setPrev(other);
this.getPrev().setNext(other);
}
Note again this is completely untested and hasn't even seen a compiler.
Make sure to think about special cases like when the list is empty or has only one element in it, and when there is only one node left unsorted in the list.
I couldn't leave this without pointing out that swap is actually a lot more complex than that. I've added a few lines to correct the pointers in the nodes before and after the nodes to be swapped. You also need to consider:
Whether either of the nodes that are swapped are at the end of the list, in which case the head (and tail if you have one) of the list will need to be updated instead of the pointers in the adjacent nodes. That's fairly obvious.
Whether the nodes to be swapped are next to each other in the list, when if you apply the normal algorithm you get nodes pointing to themselves. That's less obvious.
So the app reads from an external file a bunch of strings, each on a separate line.
For example:
and
cake
here
It is not arranged in any particular order. I need to read these letters and put them into linked list and finally sort them.
I need help on doing that:
Here is the current code:
import java.util.*;
import java.io.*;
public class LinkedList
{
static File dataInpt;
static Scanner inFile;
public static void main(String[] args) throws IOException
{
dataInpt=new File("C:\\lldata.txt");
inFile=new Scanner(dataInpt);
Node first = insertInOrder();
printList(first);
}
public static Node getNode(Object element)
{
Node temp=new Node();
temp.value=element;
temp.next=null;
return temp;
}
public static void printList(Node head)
{
Node ptr; //not pointing anywhere
for(ptr=head;ptr!=null;ptr=ptr.next)
System.out.println(ptr.value);
System.out.println();
}
public static Node insertInOrder()
{
Node first=getNode(inFile.next());
Node current=first,previous=null;
Node last=first;
int count=0;
while (inFile.hasNext())
{
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) > 0)
{
last.next=previous;
previous=last;
}
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) < 0)
{
current.next=last;
last=current;
}
previous=current;
current=getNode(inFile.next());
}
return last;
}
}
But that gives an infinite loop with "Cat".
Here is the data file:
Lol
Cake
Gel
Hi
Gee
Age
Rage
Tim
Where
And
Kite
Jam
Nickel
Cat
Ran
Jug
Here
Okay, self-study. Split the reading and inserting. Though old and new code both have 14 lines of code,
it makes it more intelligable.
public static Node insertInOrder() {
Node first = null;
while (inFile.hasNext()) {
String value = inFile.next().toString();
first = insert(first, value);
}
return first;
}
/**
* Insert in a sub-list, yielding a changed sub-list.
* #param node the sub-list.
* #param value
* #return the new sub-list (the head node might have been changed).
*/
private static Node insert(Node node, String value) {
if (node == null) { // End of list
return getNode(value);
}
int comparison = node.value.compareTo(value);
if (comparison >= 0) { // Or > 0 for stable sort.
Node newNode = getNode(value); // Insert in front.
newNode.next = node;
return newNode;
}
node.next = insert(node.next, value); // Insert in the rest.
return node;
}
This uses recursion (nested "rerunning"), calling insert inside insert. This works like a loop, or work delegation to a clone, or like a mathematical inductive proof.
Iterative alternative
also simplified a bit.
private static void Node insert(Node list, String value) {
Node node = list;
Node previous = null;
for (;;) {
if (node == null || node.value.compareTo(value) >= 0) {
Node newNode = getNode(value);
newNode.next = node;
if (previous == null)
list = newNode;
else
previous.next = newNode;
break;
}
// Insert in the rest:
previous = node;
node = node.next;
}
return list;
}
public static Node insertInOrder()
{
Node first=getNode(inFile.next());
Node current=first,previous=null;
Node last=first;
int count=0;
while (inFile.hasNext())
{
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) > 0)
{
last.next=previous;
previous=last;
}
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) < 0)
{
current.next=last;
last=current;
}
previous=current;
current=getNode(inFile.next());
}
return last;
}
First of all, you never do anything with the last line read from the file, so that's not ever inserted. You have to read the line and create the new Node before relinking next pointers.
Then, if last and previous refer to the same Node and the data of current is larger than that of previous,
if (previous!=null
&& ((String)current.value).compareTo((String)previous.value) > 0)
{
last.next=previous;
previous=last;
}
You set last.next = last, breaking the list. From the code (in particular the absence of a sort(Node) function), it seems as though you want to sort the list as it is created. But you only ever compare each new Node with one other, so that doesn't maintain order.
For each new node, you have to find the node after which it has to be inserted, scanning from the front of the list, and modify current.next and the predecessor's next.
In relatively simple code like that in your question, a good exercise to understanding it is to work through a few interations of your loop, inspecting the values of all your local variable to see the effect of your code. You can even do it by hand if the code is simple. If it is too difficult to do by hand, your code is probably too complicated. If you can't follow it, how can you know if you are doing what you intend. For example, I could be wrong, but this appears the be the state at the top of each iteration of the loop. It starts falling apart on the third time through, and by the fourth you have a severe problem as your list becomes disjointed.
1)last = first = Lol, current = previous = null
Lol->null
2)last = first = previous = Lol, current = Cake
Lol->Lol
3)first = Lol, last = Cake, previous = Cake, current = Gel
Cake->Lol->Lol
4)first = Lol, last = Cake, previous = Cake, current = Hi
Cake->Gel, Lol->Lol
Quite honestly, if I were running the course, I would consider the correct answer to be:
List<String> list = new LinkedList<String>();
// read in lines and: list.add(word);
Collections.sort(list);
Ok, I don't remember exactly school theory about insertion sort, but here is somehow a mix of what I think it is and your code:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class LinkedList {
public static class Node {
public String value;
public Node next;
}
static File dataInpt;
static Scanner inFile;
public static void main(String[] args) throws IOException {
inFile = new Scanner("Lol\r\n" + "Cake\r\n" + "Gel\r\n" + "Hi\r\n" + "Gee\r\n" + "Age\r\n" + "Rage\r\n" + "Tim\r\n" + "Where\r\n"
+ "And\r\n" + "Kite\r\n" + "Jam\r\n" + "Nickel\r\n" + "Cat\r\n" + "Ran\r\n" + "Jug\r\n" + "Here");
Node first = insertInOrder();
printList(first);
}
public static Node getNode(String element) {
Node temp = new Node();
temp.value = element;
temp.next = null;
return temp;
}
public static void printList(Node head) {
Node ptr; // not pointing anywhere
for (ptr = head; ptr != null; ptr = ptr.next) {
System.out.println(ptr.value);
}
System.out.println();
}
public static Node insertInOrder() {
Node current = getNode(inFile.next());
Node first = current, last = current;
while (inFile.hasNext()) {
if (first != null && current.value.compareTo(first.value) < 0) {
current.next = first;
first = current;
} else if (last != null && current.value.compareTo(last.value) > 0) {
last.next = current;
last = current;
} else {
Node temp = first;
while (current.value.compareTo(temp.value) < 0) {
temp = temp.next;
}
current.next = temp.next;
temp.next = current;
}
current = getNode(inFile.next());
}
return first;
}
}
And it works like a charm. Of course this far from optimal, both in terms of performance and code reuse.