Implementing Circular Linked List in java - java

I'm having a bit of an issue with implementing my circularly linked list. I'm working on a problem that requires you to implement any ADT yourself. I seem to be okay with adding nodes to the list, however I'm in unfamiliar territory when it comes to removing. I included the first two remove methods to give you an idea of where my head is at, how would I go about removing the last node in the list?
public class LinkedList {
private Node head;
private Node tail;
private int size = 0;
LinkedList() {
head = null;
current = null;
previous = null;
tail = null;
size = 0;
}
//checks if list is empty
public boolean isEmpty() {
return head == null;
}
//add new node to front of circularly linked list
public void addToFront(E x) {
if (head == null) {
head = new Node(x);
} else {
Node n = new Node(x);
x.next() = head;
head = x;
}
}
public void addtoMiddle(E x) {
x.next = current.next();
current.next = x;
size = size + 1;
}
public void addToEnd(E x) {
x.next = null;
tail.next() = x;
tail = x;
size = size + 1;
}
public void removeFirst(E x) {
if (head = null) {
System.out.println("Error! List is empty!");
} else {
head = current.next();
size = size + 1;
}
}
public void removeMiddle(E x) {
previous.next() = current.next();
current.next() = null;
size = size + 1;
}

In a circular linked list the last node's next points to the head, so you loop through your nodes until node.next.equals( head ). Note that next must never be null and if you have only one node then you have head.next = head.
In a circular doubly linked list you also have a previous node, i.e. you can iterate backwards. In that case your last node is just head.previous.
A small ascii picture:
head -next---> node -next---> node -next---> last
| ^ <---prev- <---prev- <---prev- | ^
| | | |
| |_____________________________________next_| |
|_prev_________________________________________|

I know this is not directly an answer to your question but I feel like Thomas has given the needed explanation here.
Since you have a lot of syntax or incompleteness errors in the example
I would recommend to comment out all functions so it has no more errors. Then comment them in again one by one correcting every error.
Some advices:
You use class members which are not defined e.g. current, previous.
Decide if next should be a member or function.
You need to define a class for Node (containing its members and functions), like you did for LinkedList.

Related

Remove method for a linked list. Insert method is untraditional and runs on theta(1) time

Hello all so I have a linked list here and I have to make a remove method that works properly. For example if I call remove(0) it should delete the first thing that was entered in the list and so on and so forth. This is a little bit different than most linked lists because usually the head node is at the 0ith place however in this case the head is at the end of the list. So my code so far works pretty good however I am unable to delete the head node or the last item in my list. Also if my list only has one element in it, it is also unable to be deleted. My code works for all other cases I have looked at examples for deleting the head node however it doesn't seem to work in my case. If anyone can help me out it would be greatly appreciated!
public class MyLinkedList {
private MyNode head;
private int numberElements;
public MyLinkedList() {
numberElements = 0;
head = null;
}
// runtime = \Theta(1)
// if you don't care about ordering
// every time something is inserted it becomes the head node
public void insert(MyCircle m) {
MyNode temp = new MyNode();
temp.setData(m);
temp.setNext(head);
head = temp;
numberElements++;
}
// runtime = \Theta(n)
public void remove(int index) {
if (index >= numberElements || index < 0) {
throw new RuntimeException("Index too big or too small!");
}
MyNode current = head;
if (index == numberElements) {
head = head.getNext(); // I have seen this in other examples to delete the head node. However It does not work for mine.
}
int length = numberElements - index - 2;
for (int i = 0; i < length; i++) {
current = current.getNext();
}
if (index != 0 && index != numberElements) {
current.setNext(current.getNext().getNext());
} else if (index == 0) {
current.setNext(null);
}
numberElements--;
}
// runtime = \Theta(n)
public void print() {
// loop through the list until getNext is null
MyNode current = head;
while (current != null) {
System.out.println(current.getData());
current = current.getNext();
}
}
}
I figured it out. A simple - 1 had to be added.
MyNode current = head;
if (index == numberElements ** - 1 **) {
head = head.getNext(); // I have seen this in other examples to delete the head node. However It does not work for mine.
}

Add Doubly Linked List Node in Singly Linked List

Given singly Linked List: 1 -> 2 -> 3 -> 4 -> 5 -> null
Modify middle element as doubly Linked List Node
here middle element is 3
3 -> next should point to 4
3 -> prev should point to 1
Can any one suggest how can it be done ? interviewer gave me hint use interface. but I couldn't figure it out how.
I have to iterate over this linked list and print all the node and when it reaches to the middle, print where next and prev is pointing to, then print till the end of the list.
Expected output : 1, 2, Middle: 3, Prev: 1, Next: 4, 5
I'm facing problem in adding the middle node.
So, this "works", but if this is expected to be answered on an interview, it is way too much work.
LinkedList
public class LinkedList {
public interface Linkable<V, L extends Linkable> {
V getValue();
L getNext();
void setNext(L link);
}
public static class Node implements Linkable<Integer, Linkable> {
int value;
Linkable next;
Node(int value) {
this.value = value;
}
#Override
public Integer getValue() {
return value;
}
#Override
public Linkable getNext() {
return next;
}
#Override
public void setNext(Linkable link) {
this.next = link;
}
}
private Linkable head;
public boolean isEmpty() {
return this.head == null;
}
public Linkable getHead() {
return head;
}
public void add(int v) {
Node next = new Node(v);
if (isEmpty()) {
this.head = next;
} else {
Linkable tmp = this.head;
while (tmp.getNext() != null) {
tmp = tmp.getNext();
}
tmp.setNext(next);
}
}
}
Interface
interface DoublyLinkable<V, L extends LinkedList.Linkable> extends LinkedList.Linkable<V,L> {
LinkedList.Linkable getPrev();
void setPrev(LinkedList.Linkable prev);
}
DoubleNode
public class DoubleNode extends LinkedList.Node implements DoublyLinkable<Integer, LinkedList.Linkable> {
LinkedList.Linkable prev;
public DoubleNode(int value) {
super(value);
}
#Override
public LinkedList.Linkable getPrev() {
return prev;
}
#Override
public void setPrev(LinkedList.Linkable prev) {
this.prev = prev;
}
}
Driver
Outputs
1, 2, Middle: 3, Prev: 1, Next: 4, 5
public class Driver {
public static LinkedList getList() {
LinkedList list = new LinkedList();
for (int i = 1; i <= 5; i++) {
list.add(i);
}
return list;
}
public static void main(String[] args) {
LinkedList list = getList();
LinkedList.Linkable head = list.getHead();
LinkedList.Linkable beforeMiddle = null;
LinkedList.Linkable middle = list.getHead();
LinkedList.Linkable end = list.getHead();
if (head != null) {
// find the middle of the list
while (true) {
if (end.getNext() == null || end.getNext().getNext() == null) break;
beforeMiddle = middle;
middle = middle.getNext();
end = end.getNext().getNext();
}
// Replace middle by reassigning the pointer to it
if (beforeMiddle != null) {
DoubleNode n = new DoubleNode((int) middle.getValue()); // same value
n.setPrev(list.getHead()); // point back to the front
n.setNext(middle.getNext()); // point forward to original value
beforeMiddle.setNext((DoublyLinkable) n);
middle = beforeMiddle.getNext();
}
// Build the "expected" output
StringBuilder sb = new StringBuilder();
final String DELIMITER = ", ";
head = list.getHead();
boolean atMiddle = false;
if (head != null) {
do {
if (head instanceof DoublyLinkable) {
atMiddle = true;
String out = String.format("Middle: %d, Prev: %d, ", (int) head.getValue(), (int) ((DoublyLinkable) head).getPrev().getValue());
sb.append(out);
} else {
if (atMiddle) {
sb.append("Next: ");
atMiddle = false;
}
sb.append(head.getValue()).append(DELIMITER);
}
head = head.getNext();
} while (head != null);
}
sb.setLength(sb.length() - DELIMITER.length());
System.out.println(sb.toString());
}
}
}
By definition, a single-linked list consists of single-linked nodes only, and a double-linked consists of double-linked nodes only. Otherwise. it is neither.
By definition the field prev of a double-linked list must point to the previous element.
Whatever you are supposed to build. It's something not well specified. So if you really were asked this in an interview (and did not misunderstand the question - maybe he wanted you to point out that ghis violates the interface?) this is a case for the code horror stories of http://thedailywtf.com/ - section "incompetent interviewers".
If you haven't, you'd better define a lenght() function so given one linked list you can know how many nodes does it have.
Thanks to the response of Cereal_Killer to the previous version of this answer, I noticed that the list is firstly a singly linked list, and you just have to make the middle node be linked both to the next node and to some previous node.
Now I guess that you have defined two structures (Struct, Class or whatever depending on the language you're using). So lets say you have Node_s defined as a node with only a next pointer, and Node_d with both a next and a prev pointer. (Node_d may inherite from Node_s so you just have to add the prev attribute in the child class). Knowing this, the code above should be doing what you need:
function do_it(my_LinkedList linkedList){
int i_middle;
int length = linkedList.length();
if ( (length รท 2 ) != 0 ) i_middle = length / 2;
else return -1;
Node_s aux = linkedList.first();
int index = 0;
Node_d middle= null;
while (aux != null) {
if (index == i_middle - 1){ //now aux is the middle's previous node
middle.data = aux.next.data; //aux.next is the middle singly node, we assignate the data to the new double linked node
middle.prev = aux; //as we said, aux is the prev to the middle
midle.next = aux.next.next; //so aux.next.next is the next to the middle
print(what you need to print);
}else {
print("Node " + index " next: "+ aux.next);
}//end if
index++;
aux = aux.next;
} //end while
}//end function
This previous code should be doing what you need. I wrote the answer in some kind of pseudo-java code so if you're not familiar with Java or don't understand what my pseudo-code does, please let me know. Anyway, the idea of my code may present some troubles depending on the language you're working with, so you'll have to adapt it.
Note that at the end of the execution of this program, your data structure won't be a singly linked list, and neither a double one, since you'll have linkedList.length() - 1 nodes linked in a signly way but the middle one will have two links.
Hope this helps.

Creating push and pop methods within a user defined LinkedList

Recently, my class has been studying ArrayLists and LinkedLists. This past week we received an assignment that asked us to create push and pop methods within our LinkedList stack class. I understand the logic behind stacks such that it's last-in-first-out, but I am having trouble with the actual code. I am fairly new to computer science (this being my second course ever) and this particular assignment is literally causing me to pull my hair out. I already turned this assignment in, but we have a midterm next week and I would like to do well on it. I have been all over the web and my textbook looking for help, but nothing. My professor only refers me to the TA and the TA is only concerned with helping me with the logic, not the actual code. I'll post the instructions my professor gave me below, as well as my code so far. Thanks in advance.
From the professor:
Implement stacks using the template given in the following Java
files:
CS401StackInterface.java CS401StackLinkedListImpl.java
public interface CS401StackInterface<E>
{
/**
* Get the top element on the stack.
*
* #return the first element on the stack.
*/
public E pop();
/**
* Adds an element on the top of the stack.
*
* #param e - The element to be added to the stack.
*/
public void push(E e);
/**
* Determines the number of elements in this data structure.
*
* #return the number of elements currently resident in this
* data structure.
*/
public int size();
}
Here is the actual class where I attempt to define my methods:
public class CS401StackLinkedListImpl<E> implements CS401StackInterface<E>
{
private LinkEntry<E> head;
private int num_elements;
public CS401StackLinkedListImpl()
{
head = null;
num_elements = 0;
}
public void setElement(LinkEntry<E> anElement){
head = anElement;
}
/*Append the new element to the end of the list*/
public void push(E e)
{
LinkEntry<E> temp = new LinkEntry<E>();
temp.element = e;
temp.next = head;
head = temp;
}
/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
head.next = head;
num_elements--;
return (E) head;
}
public int size()
{
LinkEntry<E> temp = new LinkEntry<E>();
for (temp = head; head != null; head = head.next)
num_elements++;
return num_elements;
}
public String toString()
{
String string = "";
LinkEntry<E> temp = new LinkEntry<E>();
for (temp = head; temp != null; temp = temp.next)
{
string += temp.element.toString() + "";
}
return string;
}
/* ------------------------------------------------------------------- */
/* Inner classes */
protected class LinkEntry<E>
{
protected E element;
protected LinkEntry<E> next;
protected LinkEntry() { element = null; next = null; }
}
}
Finally, here is my main class where I test my methods:
import java.util.*;
public class App {
public static <E> void main(String[] args) {
CS401StackLinkedListImpl<String> my_stack = new CS401StackLinkedListImpl<String>();
my_stack.push("Brian");
my_stack.push("Chris");
my_stack.push("Joe");
System.out.println("Stack size: " + my_stack.size());
my_stack.pop();
System.out.println("Stack size: " + my_stack.size());
my_stack.toString();
}
}
When I run my main class this is what it returns:
Stack size: 3
Exception in thread "main" java.lang.NullPointerException
at week6.CS401StackLinkedListImpl.pop(CS401StackLinkedListImpl.java:30)
at week6.App.main(App.java:66)
Everything I've come across just tells me to create a new Stack, which is easy because then I don't have to worry about the "innards" of the code, but that's not what I need. Thanks.
The problem is with your size method. It corrupts the value of head so that it is null. Then your call to pop gets an NPE.
You also have a problem with variable initialization - num_elements will just increase on every call to size. You can simplify this by increasing the variable on calls to push.
Also your setElement will corrupt your stack, if used, because it just sets head, without patching up the next pointers.
Sorry, I see that this is turned in homework... so here are some concrete ways to correct the code:
public CS401StackLinkedListImpl()
{
head = null;
num_elements = 0;
}
public void setElement(LinkEntry<E> anElement)
{
if (head != null)
anElement.next = head.next; //New top-of-stack needs to point to next element, if any
else
anElement.next = null;
head = anElement;
}
/*Append the new element to the end of the list*/
public void push(E e)
{
LinkEntry<E> temp = new LinkEntry<E>();
temp.element = e;
temp.next = head;
head = temp;
num_elements++; // Increase number of elements count here
}
/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
E result = head.element; // Save return value of TOS
head = head.next; // Corrected POP action
num_elements--;
return result;
}
public int size()
{
//Remove below since count is kept accurate with push/pop methods
//LinkEntry<E> temp = new LinkEntry<E>();
//for (temp = head; head != null; head = head.next)
// num_elements++;
return num_elements;
}
You might want to add an addition check in pop to throw a better exception than NPE if there are no elements, such as:
if (head == null)
throw new StackUnderflowException(); // and define a StackUnderflowException; or use a standard exception with a message
public void push(E e)
It seems ok.
public E pop()
It doensn't seem ok: you assign to the head.next element itself, this creates a loop. Then you return the actual head. You should first save current head somewhere, then update head reference to the next element and return the previous head.
public int size()
Method is wrong: first of all you instantiate a useless element to temp but you don't need it (since you will use the temp inside the loop and you should initialize it to the current head. Then check your for loop: you are using head either in the stop condition either in the end of loop iteration. You should never use head, since you are just iterating on the list and not modifying it, but just temp (check your toString code which appears to be correct).
looking at the code, it appears your Pop method is backwards.
In your push method, you assign the current head element to the 'next' attribute of the new LinkEntry, and then make that the new head. Therefor, when you pop the item off the list, you need to assign the 'next' element back to the head of the list. so your code, which is:
head.next = head;
should be:
LinkEntry<E> toReturn = head;
head = head.next;
return toReturn.element;
In effect, you are cloning the head reference to the current item at the top of the stack (so you can return it), then moving the head reference to point to the next item in the stack
/*Append the new element to the end of the list*/
public void push(E e)
{
LinkEntry<E> temp = new LinkEntry<E>();
temp.element = e;
temp.next = head;
num_elements++;//Increment count<--- Correction
head = temp;
}
/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
E returnValue =head.element ;<--- Correction
head=head.next;<--- Correction
num_elements--;//Decrement count
return returnValue;
}
public int size()
{
return num_elements;<--- Correction
}

Homework - Java - Selection Sort on my created double-linked list

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.

Inserting a node into a linked list in constant-time?

I'm working on an assignment that is telling me to assume that I have a singly linked list with a header and tail nodes. It wants me to insert an item y before position p. Can anybody please look over my code and tell me if I'm on the right track? If not, can you provide me with any tips or pointers (no pun intended)?
tmp = new Node();
tmp.element = p.element;
tmp.next = p.next;
p.element = y;
p.next = tmp;
I think I may be wrong because I do not utilize the header and tail nodes at all even though they are specifically mentioned in the description of the problem. I was thinking of writing a while loop to traverse the list until it found p and tackle the problem that way but that wouldn't be constant-time, would it?
Just write it down if you get stuck with an algorithm:
// First we have a pointer to a node containing element (elm)
// with possible a next element.
// Graphically drawn as:
// p -> [elm] -> ???
tmp = new Node();
// A new node is created. Variable tmp points to the new node which
// currently has no value.
// p -> [elm] -> ???
// tmp -> [?]
tmp.element = p.element;
// The new node now has the same element as the original.
// p -> [elm] -> ???
// tmp -> [elm]
tmp.next = p.next;
// The new node now has the same next node as the original.
// p -> [elm] -> ???
// tmp -> [elm] -> ???
p.element = y;
// The original node now contains the element y.
// p -> [y] -> ???
// tmp -> [elm] -> ???
p.next = tmp;
// The new node is now the next node from the following.
// p -> [y] -> [elm] -> ???
// tmp -> [elm] -> ???
You have the required effect, but it can be more efficient and I bet you can now find out yourself.
It is more clear to write something like:
tmp = new Node();
tmp.element = y;
tmp.next = p;
p = tmp;
Which of course does not work if p is not mutable. But your algorithm fails if p == NULL.
But what I meant to say, is, if you have problems with an algorithm, just write the effects out. Especially with trees and linked lists, you need to be sure all pointers are pointing to the righ direction, else you get a big mess.
Hint: insertion into a linked list is only constant when position n = 0, or the head of the list. Otherwise, the worst-case complexity is O(n). That's not to say that you cannot create a reasonably efficient algorithm, but it will always have at least linear complexity.
The reason why the header and tail node is given in the question is to the update the header and tail reference if the the replacement node that your creating happens to become the header or tail. In other is words, the given previous node is either a header or tail.
What you are not doing is linking the element that was before p prior to insertion of y to y. So while y is inserted before p, no one is pointing to y now (at-least not in the code snipped you showed).
You can only insert in constant time if you know the positions of the elements between which you have to insert y. If you have to search for that position, then you can never have a constant time insertion in a single link list.
How about using code that is already there? LinkedHashMap, LinkedList, LinkedHashSet. You can also check out the code and learn from it.
create a node ptr
ptr->info = item //item is the element to be inserted...
ptr->next = NULL
if (start == NULL) //insertion at the end...
start = ptr
else
temp = ptr
while (temp->next != NULL)
temp = temp->next
end while
end if
if (start == NULL) //insertion at the beginning...
start = ptr
else
temp = start
ptr->info = item
ptr->next = start
start = ptr
end if
temp = start //insertion at specified location...
for (i = 1; i < pos-1; i++)
if (start == NULL)
start = ptr
else
t = temp
temp = temp->next
end if
end for
t->next = ptr->next
t->next = ptr
In a singly LinkedList only adding a Node to the beginning of the list or creating a List with only one Node would take O(1). OR as they have provided the TailNode also Inserting the Node at End of list would take O(1).
every other inserting operation will take O(n).
The whole explanation and the 2 codes are in Java... but its easy to translate it to any other language of your choice.
I do want to help you however I am a beginner myself...
Still I have used the logic, sharing it from the queues implementation...
I have pasted two codes one is in O(N) the other contains a method called append which is in O(1)
Now, the explanation
declare the tail node with head node in the class
now in the method append class in the 2nd code below just look at the tail pointer
CASE 1: when LL empty
usually people check if (head == null) if true then they point the head to the
new Node and return
whereas what I have done is I checked if (tail == null) and if it was true
then tail = head = newnode meaning that the tail and head both now point to
the new Node to be added.
CASE 2: when LL is not empty
wait, haha, hear me out first, I know you might be thinking that what if the
LL has just 1 node currently, then what? well... for that...
this case 2 handles it automatically, in case 1 it sets the head and tail
equal to the newnode right, so it now just changes and modifies the tail node
keeping the head node intact.
this way, the head keeps pointing to the first node and the tail keeps updating and pointing to the newnodes created with each append function call.
Hope this explanation helps...
PS. check from line 24 for O(N) and 102 for O(1) and every time a newnode is added to the LL by the append method call, the tail will point to the new node to be added.
import java.io.*;
import java.util.*;
public class Solution {
// class Solution is what should be called as the LINKEDLIST class but its ok
Node head; // declaring a head for the LL
class Node { // Node class
int data; // the .data variable
Node ref; // .ref aka .next
Node(int data) { // constructor for initializing the values
this.data = data;
this.ref = null;
}
}
public void append(int data) { // i call 'to join at the end' as append
// O(N)
Node newnode = new Node(data); // new node creation
if (head == null) { // checking is head is null aka None in Py
head = newnode;
return;
}
Node curr = head; // assigning head to a curr node ready for traversal
while (curr.ref != null) { // traversal begins
curr = curr.ref;
} // traversal ends
curr.ref = newnode; // this is the last node where the join happens
}
public void p() { // i name printing function as p()
if (head == null) { // if head is null then print empty
System.out.println("Empty");
return;
}
Node curr = head; // same thing - traversal begins here
while (curr != null) {
System.out.println(curr.data);
curr = curr.ref;
} // by now all data values have been printed out already
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); // scanner class for input
Solution l = new Solution(); // object creating for LL as Solution class name
int numberOfNodes = sc.nextInt(); // input for number of NODEs in LL
for (int i = 0; i < numberOfNodes; i++) { // loop for .data values
int data = sc.nextInt();
l.append(data); // function append call for each (i)
}
l.p(); // finally print func call to display output LL
}
}
class PractGG {
Node head;
Node tail;
class Node {
int data;
Node ref;
Node(int data) {
this.data = data;
this.ref = null;
}
}
public void push(int data) {
Node newnode = new Node(data);
if (head == null) {
tail = head = newnode;
return;
}
newnode.ref = head;
head = newnode;
}
public void append(int data) {
// O(1)
Node newnode = new Node(data);
if (tail == null) {
tail = head = newnode;
return;
}
tail.ref = newnode;
tail = newnode;
}
public void p() {
if (head == null) {
System.out.println("Empty");
}
Node curr = head;
while (curr!=null) {
System.out.print(curr.data + "==>");
curr = curr.ref;
}
System.out.println();
}
public static void main(String[] args) {
PractGG l = new PractGG();
l.append(1);
l.append(2);
l.append(3);
l.p();
}
}

Categories

Resources