Excuse my ignorance but I am beginning to prepare for my first technical interview and came across this question and answer on the topic linkedlist
Question: Implement an algorithm to delete a node in the middle of a single linked list, given only access to that node
public static boolean deleteNode(LinkedListNode n) {
if (n == null || n.next == null) {
return false; // Failure
}
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
return true;
}
I want to start playing with this code (making changes compile test) but I'm not sure how to start doing this in Java. I cannot find the LinkedListNode class in Java docs.
This might be a very silly question but if someone can point me in the right direction - will appreciate it.
EDIT
Thanks for the quick and useful responses. I guess my question was not very clear. The algorithm above was provided as a solution to that question. I wanted to know how to implement that in Java so I can play around with the code.
thanks
The code will only work properly if there's a tail node on the list.
The algorithm works with the following logic
When referring to the node to be deleted, call it "curr"
When referring to the node before "curr", call it "prev"
When referring to the node after "curr", call it "next"
To effectively delete our node, "prev".next should point to "next"
It currently points to "curr"
Our problem is that we have no reference to "prev"
We know "prev".next points to "curr"
Since we cannot change the fact that "prev".next points to "curr",
we must have "curr" gobble up "next"
We make "curr"s data be "next"s data
We make "curr"s next be "next"s next
The reason this only works if there's a tail guard
is so we can make "next" be the "tail" node of the
list. (Its data is null and it's next is null.) Otherwise,
"prev".next would still be pointing to something.
Here's a class that uses LinkedListNode. I should note that if you're applying for a position as a programmer, you should be able to do this basically from memory. :-)
class LinkedList<E> {
static class LinkedListNode<E> {
E data;
LinkedListNode<E> next;
}
/**
* Not exactly the best object orientation, but we'll manage
*/
static <E> E deleteNode(LinkedListNode<E> node) {
if(node == null || node.next == null) return null;
E retval = node.data;
LinkedListNode<E> next = node.next;
node.data = next.data;
node.next = next.next;
return retval;
}
private LinkedListNode<E> head;
private LinkedListNode<E> tail;
public LinkedList() {
this.head = new LinkedListNode<E>();
this.tail = new LinkedListNode<E>();
head.next = tail;
}
public void addLast(E e) {
LinkedListNode<E> node = new LinkedListNode<E>(); // e and next are null
tail.data = e;
tail.next = node;
tail = node;
}
public void addFirst(E e) {
LinkedListNode<E> node = new LinkedListNode<E>(); // e and next are null;
node.next = head.next;
node.data = e;
head.next = node;
}
public E deleteFirst() {
LinkedListNode<E> first = head.next;
head.next = first.next;
return first.data;
}
public E deleteLast() {
// cannot do without iteration of the list! :-(
throw new UnsupportedOperationException();
}
public LinkedListNode<E> findFirst(E e) {
LinkedListNode<E> curr = head.next;
while(curr != null) {
if(curr.data != null && curr.data.equals(e)) return curr;
curr = curr.next;
}
return null;
}
public void print() {
LinkedListNode<E> curr = head.next;
while(curr.next != null) {
System.out.println(curr.data);
curr = curr.next;
}
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.addLast("Apple");
list.addLast("Bear");
list.addLast("Chair");
list.addLast("Dirt");
//list.print();
LinkedListNode<String> bear = list.findFirst("Bear");
deleteNode(bear);
list.print();
}
}
This class is most likely a hypothetical class used for this Linked List example question.
LinkedListNode is a class that you will define to hold data. To get your above example to work - I've quickly written this code (just to make you understand the simple concept) in which I am creating 3 nodes (which are linked to each other) and then deleting the middle one calling the deleteNode method that you have specified in your question.
The code is pretty self explanatory. Let me know if this helps.
Good Luck
class LinkedListNode
{
public Object data;
public LinkedListNode next;
public LinkedListNode(Object data) {
this.data = data;
}
}
class DeleteNodeLinkedList
{
public static void main(String[] args)
{
LinkedListNode node_1 = new LinkedListNode("first");
LinkedListNode node_2 = new LinkedListNode("second");
node_1.next = node_2;
LinkedListNode node_3 = new LinkedListNode("third");
node_2.next = node_3;
System.out.println("*** Print contents of linked list");
LinkedListNode current = node_1;
while (current != null) {
System.out.println(current.data);
current = current.next;
}
System.out.println("*** Now delete second node");
deleteNode(node_2);
System.out.println("*** Print after deleting second node");
current = node_1;
while (current != null) {
System.out.println(current.data);
current = current.next;
}
}
public static boolean deleteNode(LinkedListNode n)
{
if (n == null || n.next == null) {
return false; // Failure
}
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
return true;
}
}
The important details in this question pertain to data structures, java is just the language that is being used to implement in this case.
You should read the wikipedia article about linked lists, and for this question be careful that your solution doesn't produce any dangling references or orphan nodes.
Do some searches on the two terms in bold, and make sure that you understand them
Your question is bit confusing. whether you want a logic to remove a node in a singly linkedlist or you want to learn and use java LinkedlistNode.
if you are in second the following link will help you
LinkedListNodee
or if you want the logic
let P the pointer to the current node
P->data = P->next->data
Q=P->next
P->next=Q->next
delete(Q)
Related
I think I know what the problem may be (a misunderstanding on Global vs. Local variables), but would like further verification on why it is not doing what I would like it to.
So, originally, I was just messing around and tried to implement the LinkedList delete method as follows :
(Also, I know most of this looks a mess right now, I think I am doing some bad practices, so you may be frank)
// Practicing with Lists...
public class ListPrac {
/*
Implement Delete for
singly-linked linked list
*/
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
delete(head, 1);
System.out.println("done");
}
public static int delete(ListNode head, int deleteMe) {
ListNode temp = head;
ListNode prev = null;
// need to check if it is first and
// need to check if it is at the end...
if (temp != null && temp.dat == deleteMe) {
temp = temp.next;
return deleteMe;
}
// ^ two edge cases...
while (temp != null) {
int curVal = temp.dat;
if (curVal == deleteMe && head.dat == curVal) {
head = temp.next;
return deleteMe; // done...
}
if (curVal == deleteMe) {
if (temp.next != null) {
prev.next = temp.next;
return deleteMe; // done...
}
}
prev = temp;
temp = temp.next;
}
return -1; // not found, so not deleted...
}
public static class ListNode {
int dat;
ListNode next;
public ListNode(int val) {
dat = val;
next = null;
}
}
}
When I debug this and check what the head looks like in the end, it still shows 1->2->3->4,
but as I went through the method, it seemed to be doing the right thing for when I removed a middle element (for ex, removing 3 yields giving me 1->2->4 at the end)
When looking at geeksforgeeks they implement it like this (and it works fine)
(this is just a snippet with delete rest can be found at https://www.geeksforgeeks.org/linked-list-set-3-deleting-node/):
class LinkedList1
{
Node head; // head of list
/* Linked list Node*/
class Node
{
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
/* Given a key, deletes the first occurrence of key in linked list */
void deleteNode(int key)
{
// Store head node
Node temp = head, prev = null;
// If head node itself holds the key to be deleted
if (temp != null && temp.data == key)
{
head = temp.next; // Changed head
return;
}
// Search for the key to be deleted, keep track of the
// previous node as we need to change temp.next
while (temp != null && temp.data != key)
{
prev = temp;
temp = temp.next;
}
// If key was not present in linked list
if (temp == null) return;
// Unlink the node from linked list
prev.next = temp.next;
}
}
(There may be other things wrong with my code, but right now I am just focusing on removal of the first element not working)
I think the problem may be that I do not fully understand what is happening globally vs. locally if that makes sense?
For further clarification :
(Also further looking into it, I think there are a lot of differences in approach to mine vs. geeksforgeeks, but I think I narrowed down where my problem lies) Anyways, after moving some things around, I think my question is really about why their delete method works with a linked list object vs. just a linked list built using ListNodes in main, for example below :
// Practicing with Lists...
public class ListPrac1 {
public static ListNode head;
public static ListNode headExample; // the different example
public static void main(String[] args) {
ListPrac1 ll1= new ListPrac1();
ll1.push(4);
ll1.push(3);
ll1.push(2);
ll1.push(1);
ll1.delete(1);
System.out.println("done");
System.out.println("\nLinked List after Deletion of 1:");
ll1.printList();
// This is what they did basically while creating a LinkedList
// Object I guess and it works...
// but... with the same structure of delete method and just
// using ListNodes to build a list starting with
// variable headExample instead and then calling deleteMine.
// (which has the same structure as delete except a reference to
// the new head...)
ListNode headExample = new ListNode(1);
headExample.next = new ListNode(2);
headExample.next.next = new ListNode(3);
headExample.next.next.next = new ListNode(4);
deleteMine(1);
System.out.println();
System.out.println("\nLinked List starting with headExample after Deletion of 1:");
while (headExample != null) {
System.out.print(headExample.dat + " ");
headExample = headExample.next;
}
}
public static void printList() {
ListNode tnode = head;
while (tnode != null)
{
System.out.print(tnode.dat+" ");
tnode = tnode.next;
}
}
public static int delete(int deleteMe) {
// Store head node
ListNode temp = head, prev = null;
// If head node itself holds the key to be deleted
if (temp != null && temp.dat == deleteMe)
{
head = temp.next; // Changed head
return deleteMe;
}
// Search for the key to be deleted, keep track of the
// previous node as we need to change temp.next
while (temp != null && temp.dat != deleteMe)
{
prev = temp;
temp = temp.next;
}
// If key was not present in linked list
if (temp == null) return -1;
// Unlink the node from linked list
prev.next = temp.next;
return deleteMe;
}
public static int deleteMine(int deleteMe) {
// Store head node
ListNode temp = headExample, prev = null;
// If head node itself holds the key to be deleted
if (temp != null && temp.dat == deleteMe)
{
headExample = temp.next; // Changed head
return deleteMe;
}
// Search for the key to be deleted, keep track of the
// previous node as we need to change temp.next
while (temp != null && temp.dat != deleteMe)
{
prev = temp;
temp = temp.next;
}
// If key was not present in linked list
if (temp == null) return -1;
// Unlink the node from linked list
prev.next = temp.next;
return deleteMe;
}
public static void push(int new_data) {
ListNode new_node = new ListNode(new_data);
new_node.next = head;
head = new_node;
}
public static class ListNode {
int dat;
ListNode next;
public ListNode(int val) {
dat = val;
next = null;
}
}
}
Output yields :
done
Linked List after Deletion of 1:
2 3 4
Linked List starting with headExample after Deletion of 1:
1 2 3 4
So it works for their way when creating a LinkedList, but not the other way where I make one with Nodes.
The delete and deleteMine methods are the same except deleteMine references headExample (which is what builds my second list in the second part)
So, my question really is:
Shouldn’t the delete work in both cases? Since both the LinkedList and headExample reference their respective head variables, why is headExample not being modified after delete, but the LinkedList ll1 is?
I think the problem of your implementation is that you do not have a 'List'-object.
You have some instances of the ListNode class.
For a LinkedList you need to have an additional class that represents the List.
That List-class should have a ListNode variable that represents the head of the list. Look at the
class LinkedList1
{
Node head; // head of list
part. It has a member named 'head'.
When the delete method is called it changes the head member variable of the list object.
If the class ListPrac represents your list a starting point could look like this:
public class ListPrac {
// each instance of ListPrac has a ListNode that represents the head of the list.
ListNode head;
public static void main(String[] args) {
ListPrac theList = new ListPrac();
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
// here we assign a ListNode as the head of the list.
theList.head = head;
// the delete method is invoked on the list.
theList.delete(1);
//print the list to the console.
System.out.println(theList);
}
// not static because we operate on a ListPrac instance.
public int delete(int deleteMe) {
//...
public static class ListNode {
//...
#Override
public String toString(){
String nextNodeAsString = next == null ? "null" : next.toString();
return "{data="+dat+",next="+nextNodeAsString+"}";
}
}
//...
#Override
public String toString(){
return "a list: {head="+head.toString()+"}";
}
}
In the next step you should compare your and the other solution and try to spot the error.
Happy coding :)
I have written my own linked list and am reading integers from a file into the list and printing them out. However, only the head of my list is printing and nothing else. I've been staring at this code for so long I feel insane, can anyone help?
Method in a separate 'files' class that reads in a file of integers separated by whitespace. This method will take the next integer and add it to my linked list.
public void readValues() {
LinkedList list = new LinkedList();
while(scan.hasNextInt()) {
Integer someData = scan.nextInt();
list.addNode(someData);
}
list.printList();
}
This method is in my LinkedList class which takes the data sent from my readValues method in my files class.
public void addNode(Integer someData) {
myNode = new LinkedNode(someData,null);
//initialize node if this is first element
if (head == null) {
head = myNode;
size++;
}
else if (myNode.getNext() == null) {
myNode.setNext(myNode);
size ++;
}
else if (myNode.getNext() != null) {
while(myNode.getNext() != null) {
myNode = myNode.getNext();
}
myNode.setNext(myNode);
size++;
}
}
This method is also in my LinkedList class and successfully prints the head of my list which with my data is the number 40 followed by ---> and then nothing else. It should print ever other integer read in from my file.
public void printList() {
LinkedNode current = head;
if (head == null) {
System.out.print("list is empty");
return;
}
while(current != null) {
System.out.print(current.getElement());
System.out.print(" --> ");
current = current.getNext();
}
}
LinkedNode class:
public class LinkedNode {
Integer data;
LinkedNode next;
public LinkedNode(Integer someData, LinkedNode next) {
this.data = someData;
this.next = null;
}
public int getElement() {
return data;
}
public void setElement(Integer data) {
this.data = data;
}
public LinkedNode getNext() {
return next;
}
public void setNext(LinkedNode next) {
this.next = next;
}
public String toString() {
return data + "";
}
}
Your code has a small bug in the if else conditions in your addNode() method due to which your data is not getting added in the list.
Root Cause
When you add a new node to your list,
In the first iteration
The head is currently null and hence the first if conditions becomes true and your first node gets added (That's why you got the data 40).
In the Subsequent iteration(s)
your else if condition checks the myNode's next pointer which will always be null (as per the constructor) and thus it's next pointer points towards itself. The nodes created from here do not become the part of the list as the next pointer of head was never assigned to any of these and these nodes also point to themselves only.
Solution
I made a little modification in the if else conditions:
public void addNode(Integer someData) {
LinkedNode myNode = new LinkedNode(someData,null);
//initialize node if this is first element
if (head == null) {
head = myNode;
size++;
}
else if (head.getNext() == null) {
head.setNext(myNode);
size ++;
}
else if (head.getNext() != null) {
System.out.println("in second else if");
LinkedNode n = head;
while(n.getNext() != null) {
n = n.getNext();
}
n.setNext(myNode);
size++;
}
}
PS: Try debugging your code with dry run, it's a great mental exercise and helps in boosting the learning curve significantly too. All the best! :)
The problem is with your addNode() method. Inside the addNode() method you are first creating a new node named mynode. Now when the head is null it sets head to mynode, thats ok. But when the head is not null the mynode is not being added to the list. Thats why only the first element exist and other's are getting lost.
Hope this helps. Let me know if I can help with anything else. Happy coding!
I had basically no issue with linked lists in C++, but this is getting to me for some reason. I had a single node being printed out using the other classes in the package that were provided, but as I go on I just keep running into walls.
The code below is in shambles due to me tinkering around. I just have no idea where to go from here. As of now that is getting a null pointer exception.
Just for information: poll() is just removing the current head and returning it, offer() is adding to the rear. As of now the exception is at oldLast.next = last in the offer method.
I am not asking for anyone to completely solve this. I just need some tips to progress.
public class FIFOQueue implements Queue {
//put your name as the value of the signature.
String signature = "name";
Node head = new Node(null);
Node pointer = head;
Node first;
Node last;
Node prev;
Node curr;
class Node {
Process process;
Node next;
Node(Process p) {
this.process = p;
this.next = null;
}
}
#Override
public void offer(Process p) {
if(head == null)
{
head = new Node(p);
first = head;
last = head;
}
else
{
Node oldLast = last;
Node newNode = new Node(p);
last = newNode;
oldLast.next = last;
}
}
#Override
public Process poll() {
if(isEmpty())
throw new NoSuchElementException();
Node oldPointer = first;
first = first.next;
head = first;
return oldPointer.process;
}
#Override
public boolean isEmpty() {
return head == null;
}
#Override
public String getSignature() {
return signature;
}
}
I think your core issue is here:
Node prev;
Node curr;
These are confusing you. Remove them.
Node prev; - This should be in the Node class.
Node curr; - This should be a local variable, not an instance variable.
Also
Node head = new Node(null);
does not gel with
if(head == null)
{
head = new Node(p);
Either make head == null mean the list is empty or something else - but be consistent.
(Posted on behalf of the OP).
public void offer(Process p) {
if(head.process == null)
{
head = new Node(p);
first = head;
last = head;
}
last.next = new Node(p);
last = last.next;
}
This solved my issue. Can't believe I let this confuse me.
I am confused as to how to add to the front of the linked list.
/**
* data is added to the front of the list
* #modifies this
* #ffects 2-->4-->6 becomes data-->2-->4-->6
*/
public void insert(E data) {
if (front == null)
front = new Node(data, null);
else {
Node temp = new Node(data, front);
front = temp;
}
}
This creates a cycle. How do I avoid that?
I have a LinkedList class which holds the front Node, in a variable called front.
I have a Node class within this LinkedList class.
Any help would be appreciated.
Thank you.
Don't you have access to "Next" node ?
In that case
public void insert(E data) {
if (front == null) {
front = new Node(data, null);
} else {
Node temp = new Node(data, null);
temp.next = front;
front = temp;
}
}
--
class LinkedList {
Node front;
LinkedList() {
front = null;
}
public void AddToFront(String v) {
if (front == null) {
front = new Node(v);
} else {
Node n = new Node(v);
n.next = front;
front = n;
}
}
}
class Node {
public Node next;
private String _val;
public Node(String val) {
_val = val;
}
}
I'm assuming that the Node constructor takes a next pointer as its 2nd argument, in which case I don't see anything obvious wrong with this code. This really sounds like a homework question. If it is, you should tag it as such.
With my limited linked list knowledge, I would venture this:
Node temp = new Node(data);
temp.next = front;
front = temp;
You might want to wait around for somebody to confirm though.
This creates a cycle. How do I avoid that?
It is not possible to know for sure without the rest of the code for your linked list implementation, but the code that you have supplied doesn't look like it creates a cycle at all.
If a cycle is being created, it is most likely being created elsewhere. Alternatively, you / your tests are misdiagnosing some other failure as being caused by a cycle.
If you need more help, post more code / evidence ... particularly the Node constructor, and the code that makes you think you have a cycle.
Add a new node and if the current head is not null, then point the current head to the newly created node as the next node.
Node insert(Node head,int x) {
Node node = new Node();
node.data = x;
if(head != null) {
node.next = head;}
return node;
}
This is my Implementation of Inserting a node to front or head of the Linked List in Java.
void insertAtHead(Object data){
if(head==null) {
head = new Node(data);
}
Node tempNode = new Node(data);
Node currentNode = head;
tempNode.setNext(currentNode.getNext());
head.setNext(tempNode);
incrementCounter();
}
A simple and quick [ may not be efficient ] solution is to create a temporary new LinkedList with the new element and merge the two lists together with the temp-list in the front.
see the example below
import java.util.*;
public class Main
{
public static Queue<Integer> addFirst(Queue<Integer> intQueue, Integer i){
Queue<Integer> intQueue2 = new LinkedList<Integer>();
intQueue2.add(i);
intQueue2.addAll(intQueue);
intQueue = intQueue2;
return intQueue;
}
public static void main(String[] args) {
System.out.println("Hello LinkedList");
Queue<Integer> intQueue = new LinkedList<Integer>();
intQueue.add(3);
intQueue.add(4);
intQueue.add(5);
intQueue = addFirst(intQueue,2);
intQueue = addFirst(intQueue,1);
System.out.println(intQueue);
}
}
a linear linked list is a set of nodes. This is how a node is defined (to keep it easy we do not distinguish between node an list):
class Node{
Object data;
Node link;
public Node(Object pData, Node pLink){
this.data = pData;
this.link = pLink;
}
public String toString(){
if(this.link != null){
return this.data.toString() + this.link.toString();
}else{
return this.data.toString() ;
}
}
public void inc(){
this.data = new Integer((Integer)this.data + 1);
}
public void lappend(Node list){
Node child = this.link;
while(child != null){
child = child.link;
}
child.link = list;
}
public Node copy(){
if(this.link != null){
return new Node(new Integer((Integer)this.data), this.link.copy());
}else{
return new Node(new Integer((Integer)this.data), null);
}
}
public Node invert(){
Node child = this.link;
while(child != null){
child = child.link;
}
child.link = this;....
}
}
I am able to make a deep copy of the list. Now I want to invert the list so that the first node is the last and the last the first. The inverted list has to be a deep copy.
I started developing the invert function but I am not sure. Any Ideas?
Update: Maybe there is a recursive way since the linear linked list is a recursive data structure.
I would take the first element, iterate through the list until I get to a node that has no child and append the first element, I would repeat this for the second, third....
I sometimes ask this question in interviews...
I would not recommend using a recursive solution, or using a stack to solve this. There's no point in allocating O(n) memory for such a task.
Here's a simple O(1) solution (I didn't run it right now, so I apologize if it needs some correction).
Node reverse (Node current) {
Node prev = null;
while (current != null) {
Node nextNode = current.next;
current.next = prev;
prev = current;
current = nextNode;
}
return prev;
}
BTW: Does the lappend method works? It seems like it would always throw a NullReferenceException.
There's a great recursive solution to this problem based on the following observations:
The reverse of the empty list is the empty list.
The reverse of a singleton list is itself.
The reverse of a list of a node N followed by a list L is the reverse of the list L followed by the node N.
You can therefore implement the reverse function using pseudocode along these lines:
void reverseList(Node node) {
if (node == null) return; // Reverse of empty list is itself.
if (node.next == null) return; // Reverse of singleton list is itself.
reverseList(node.next); // Reverse the rest of the list
appendNodeToList(node, node.next); // Append the new value.
}
A naive implementation of this algorithm runs in O(n2), since each reversal requires an append, which requires an O(n) scan over the rest of the list. However, you can actually get this working in O(n) using a clever observation. Suppose that you have a linked list that looks like this:
n1 --> n2 --> [rest of the list]
If you reverse the list beginning at n2, then you end up with this setup:
n1 [reverse of rest of the list] --> n2
| ^
+------------------------------------------+
So you can append n1 to the reverse of the rest of the list by setting n1.next.next = n1, which changes n2, the new end of the reverse list, to point at n1:
[reverse of the rest of the list] --> n2 --> n1
And you're golden! Again more pseudocode:
void reverseList(Node node) {
if (node == null) return; // Reverse of empty list is itself.
if (node.next == null) return; // Reverse of singleton list is itself.
reverseList(node.next); // Reverse the rest of the list
node.next.next = node; // Append the new value.
}
EDIT: As Ran pointed out, this uses the call stack for its storage space and thus risks a stack overflow. If you want to use an explicit stack instead, you can do so like this:
void reverseList(Node node) {
/* Make a stack of the reverse of the nodes. */
Stack<Node> s = new Stack<Node>();
for (Node curr = node; node != null; node = node.next)
s.push(curr);
/* Start unwinding it. */
Node curr = null;
while (!s.empty()) {
Node top = s.pop();
/* If there is no node in the list yet, set it to the current node. */
if (curr == null)
curr = top;
/* Otherwise, have the current node point to this next node. */
else
curr.next = top;
/* Update the current pointer to be this new node. */
curr = top;
}
}
I believe that this similarly inverts the linked list elements.
I would treat the current list as a stack (here's my pseudo code):
Node x = copyOf(list.head);
x.link = null;
foreach(node in list){
Node temp = copyOf(list.head);
temp.link = x;
x = temp;
}
At the end x will be the head of the reversed list.
I more fammiliar whit C, but still let me try. ( I just do not sure if this runs in Java, but it should)
node n = (well first one)
node prev = NULL;
node t;
while(n != NULL)
{
t = n.next;
n.next = prev;
prev = n;
n = t;
}
Reversing a single-linked list is sort of a classic question. It's answered here as well (and well answered), it does not requires recursion nor extra memory, besides a register (or 2) for reference keeping.
However to the OP, I guess it's a school project/homework and some piece of advice, if you ever get to use single linked list for some real data storage, consider using a tail node as well. (as of now single linked lists are almost extinct, HashMap buckets comes to mind, though).
Unless you have to check all the nodes for some condition during 'add', tail is quite an improvement. Below there is some code that features the reverse method and a tail node.
package t1;
public class SList {
Node head = new Node();
Node tail = head;
private static class Node{
Node link;
int data;
}
void add(int i){
Node n = new Node();
n.data = i;
tail = tail.link =n;
}
void reverse(){
tail = head;
head = reverse(head);
tail.link = null;//former head still links back, so clear it
}
private static Node reverse(Node head){
for (Node n=head.link, link; n!=null; n=link){//essentially replace head w/ the next and relink
link = n.link;
n.link = head;
head = n;
}
return head;
}
void print(){
for (Node n=head; n!=null;n=n.link){
System.out.println(n.data);
}
}
public static void main(String[] args) {
SList l = new SList();
l.add(1);l.add(2);l.add(3);l.add(4);
l.print();
System.out.println("==");
l.reverse();
l.print();
}
}
I was wondering something like that(I didnt test it, so):
invert(){
m(firstNode, null);
}
m(Node v, Node bef){
if(v.link != null)
m(v.link,v);
else
v.link=bef;
}
Without much testing,
Node head = this;
Node middle = null;
Node trail = null;
while (head != null) {
trail = middle;
middle = head;
head = head.link;
middle.link = trail;
}
head = middle;
return head;
public ListNode Reverse(ListNode list)
{
if (list == null) return null;
if (list.next == null) return list;
ListNode secondElem = list.next;
ListNode reverseRest = Reverse(secondElem);
secondElem.Next = list;
return reverseRest;
}
Hope this helps.