I have been grinding leetcode all day, so far 3 of the problems I did on Eclipse have worked 100% but when I run them on leetcode's IDE I always get null pointer errors. Here is a current example of my code and the problem I am currently doing: 138. Copy List with Random Pointer , which is just supposed to copy a linked list but by value and not reference.
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
//MY CODE STARTS BELOW ==============================================================
class Solution {
Node n, r, pointer, output;
public Node copyRandomList(Node head) {
//Handling weird inputs
if (head == null){return head;}
Node output = new Node(head.val);
n = output; r = output;
pointer = head;
nextHandler();
randHandler();
return output;
}
public void nextHandler(){
if (pointer.next != null){
n.next = new Node(pointer.next.val);
n = n.next;
pointer = pointer.next;
nextHandler();
}
}
public void randHandler(){
if (pointer.random != null){
r.random = new Node(pointer.random.val);
r = r.next;
pointer = pointer.next;
randHandler();
}
}
}
I guess Java is not like C/C++, does not have passing by reference, uses passing by value. Probably, there is a bug in your algorithm. You can just use a debugger for that, even on LeetCode you can simply print things out.
We'd simply use a HashMap for solving this problem.
This'll pass:
public final class Solution {
public static final Node copyRandomList(
final Node head
) {
HashMap<Node, Node> map = new HashMap<>();
return clone(head, map);
}
private static final Node clone(
final Node head,
final HashMap map
) {
if (head == null) {
return null;
}
Node ptr = new Node(head.val);
map.put(head, ptr);
ptr.next = clone(head.next, map);
ptr.random = (Node) map.get(head.random);
return ptr;
}
}
Here is LeetCode's most efficient solution (which is better), O(N) runtime, constant memory:
/*
// Definition for a Node.
class Node {
public int val;
public Node next;
public Node random;
public Node() {}
public Node(int _val,Node _next,Node _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
public class Solution {
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
// Creating a new weaved list of original and copied nodes.
Node ptr = head;
while (ptr != null) {
// Cloned node
Node newNode = new Node(ptr.val);
// Inserting the cloned node just next to the original node.
// If A->B->C is the original linked list,
// Linked list after weaving cloned nodes would be A->A'->B->B'->C->C'
newNode.next = ptr.next;
ptr.next = newNode;
ptr = newNode.next;
}
ptr = head;
// Now link the random pointers of the new nodes created.
// Iterate the newly created list and use the original nodes' random pointers,
// to assign references to random pointers for cloned nodes.
while (ptr != null) {
ptr.next.random = (ptr.random != null) ? ptr.random.next : null;
ptr = ptr.next.next;
}
// Unweave the linked list to get back the original linked list and the cloned list.
// i.e. A->A'->B->B'->C->C' would be broken to A->B->C and A'->B'->C'
Node ptr_old_list = head; // A->B->C
Node ptr_new_list = head.next; // A'->B'->C'
Node head_old = head.next;
while (ptr_old_list != null) {
ptr_old_list.next = ptr_old_list.next.next;
ptr_new_list.next = (ptr_new_list.next != null) ? ptr_new_list.next.next : null;
ptr_old_list = ptr_old_list.next;
ptr_new_list = ptr_new_list.next;
}
return head_old;
}
}
References
For additional details, please see the Discussion Board where you can find plenty of well-explained accepted solutions with a variety of languages including low-complexity algorithms and asymptotic runtime/memory analysis1, 2.
Related
I have the following code and in the code line where it says 't = obj.deleteNode(obj,3);', I think this should delete 4 and 5. I'm not sure why its not doing it. I also think 'head.next' is Node#788 which is attributed to the number 4. 'head' and 'n' are Node#787 because I passed in the parameter 'obj' which begins with the address Node#787.
class Node {
Node next = null;
int data;
public Node(int d) {
data = d;
Node next = null;
}
Node appendToTail(int d) {
Node end = new Node(d);
Node n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
return end;
}
Node deleteNode(Node head, int d){
if(head == null) return null;
Node n = head;
if(n.data == d){
return head.next;
}
while(n.next != null){
if(n.next.data == d){
n.next = n.next.next;
return head;
}
n = n.next;
}
return head;
}
public static void main(String[] args) {
Node t;
Node obj = new Node(3);
t = obj.appendToTail(4);
t = obj.appendToTail(5);
t = obj.deleteNode(obj,3);
for (t = obj; t != null; t = t.next) {
System.out.println(t.data);
}
}
}
///
Output:
3
4
5
///
Expected output:
3
it says t = obj.deleteNode(obj,3);, I think this should delete 4 and 5.
No, it shouldn't. Your list is 3→4→5, so deleting the node with 3 should result in 4→5. That is what deleteNode is supposed to do: it should find the node that has the given value (3 in this case), and remove only that node, making sure that the preceding node (if any) is rewired to link to the node that follows it (if any).
However, your code has some logical errors:
You shouldn't reference obj after you have deleted that node. It is still there as long as you reference it, but you should only continue with the reference that deleteNode returns.
Don't pass a node reference to the deleteNode: the head of the list is supposed to be the instance on which you call deleteNode.
Don't capture the return value of insertNode unless you have good reason to use it. This is because it returns the newly added node, not (necessarily) the head of the list.
Use meaningful variable names: replace t with `head
Here is how I would code it:
class Node {
Node next = null;
int data;
public Node(int d) {
data = d;
Node next = null;
}
Node appendToTail(int d) {
Node end = new Node(d);
Node n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
return end;
}
Node deleteNode(int d){ // <-- change parameter list
Node node = this; // Assume `this` is the head of the list
if(node.data == d){
return this.next;
}
while(node.next != null){
if(node.next.data == d){
node.next = node.next.next;
return this;
}
node = node.next;
}
return this;
}
public static void main(String[] args) {
Node head = new Node(3);
// Don't assign the return value of appendToTail to a variable.
// However, chaining can be useful
head.appendToTail(4).appendToTail(5);
// Don't pass a node as argument, but capture the return value
// to be the (new) head of the list
head = head.deleteNode(3);
for (Node node = head; node != null; node = node.next) {
System.out.println(node.data);
}
}
}
When you are trying to delete node 3 which is head node you are just returning head.next in that case which is stored in 't' but later you are looping through obj which is still pointing to node 3
try this
if(n.data == d){
head = head.next;
return head;
}
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'm trying to learn about linked list and it has been little challenging for me. I'm trying to reverse the link list with recursive method. Here is my code:
public class ListNode {
Node head = null;
int nodeCount= 0;
int counter = 0;
ListNode(){
head = null;
}
public void insertNode( String name ) {
if (head == null) {
head = new Node(name, null);
nodeCount++;
} else {
Node temp = new Node(name, null);
temp.next = head;
head = temp;
nodeCount++;
}
}
public Node reverseTest(Node L){
// Node current = new Node(null,null);
if(L == null || L.next ==null){
return L;
}
Node remainingNode = reverseTest(L.next);
Node cur = remainingNode;
while(cur.next !=null){
cur=cur.next;
}
L.next = null;
cur.next = L;
return remainingNode;
}
public static void main(String[] args){
ListNode newList = new ListNode();
newList.insertNode("First");
newList.insertNode("Second");
newList.insertNode("Third");
newList.insertNode("Fourth");
newList.reverseTest(newList.head);
}
}
The problem I'm having with is the reverse method. When the method is over it only returns the last node with the value "First".Through the entire recursion remainingNode only holds and returs value from the base case which is confusing me. I was excepting it to move further through the nodes. After the method is executed newList holds only one node with next node as null and that node is the head now. I was assuming it will reverse the linkedlist with the sequence First --> Second--> Third --> Fourth. What am I doing wrong?
Actually, everything works here. Your only problem is in your main method: you don't get the result of your method.
newList.reverseTest(newList.head);
You need to actually set the new head with the result:
newList.head = newList.reverseTest(newList.head);
This would have been easier to see if you had declared your method static:
newList.head = ListNode.reverseTest(newList.head);
As a bonus, here is a fully recursive equivalent:
public static Node reverse(Node head) {
if (head == null || head.next == null) {
return head;
}
Node newHead = reverse(head.next);
// head.next points to the new tail, we push the former head at the end
head.next.next = head;
// now head has become the new tail, we cut the end of the list
head.next = null;
return newHead;
}
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)
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.