Return the deleted node in java RECURSIVELY - java

I learned most of the linked data structures using C++ where there is pass by reference available to you and recursion is pretty straightforward. I recently switched to Java and I always get confused with the recursive versions of these structures.
I wanna take the node out of the list. But I want to return the node. When I return the deleted node from the else if branch, it expectedly messes up the list. But I can't see a way around it.
public node deleteval (int val){
node prev = head;
head = deleteval(head,prev,val);
return head;
}
private node deleteval(node head,node prev, int val){
if(head == null){
return null;
}
else if (head.value == val){
prev.next = head.next;
node deleted = head;
head = prev;
return head.next;
}
prev = head;
head.next = deleteval(head.next,prev,val);
return head;
}
This is not a homework, just trying to understand. Thanks for any input.

To delete a node you only need to do prev.next = head.next and handle the edge case for root node. There is no need for a stack or any other supporting data structure, you simply recurse deeper into the list until you find the value or reach the end.
private Node root;
public Node deleteVal(int val) {
return deleteRec(root, null, val);
}
private Node deleteRec(Node head, Node prev, int val) {
if (head == null) {
return null;
}
if (head.value == val) {
if (prev != null) {
prev.next = head.next; // deleting non-root node
} else {
root = null; // deleting root node
}
return head;
}
return deleteRec(head.next, head, val);
}

Related

Recursive code for reversing a linked list is not working properly

Here tail is a pointer to the last element of linked list.
This code only works when there are odd numbers of nodes in a linked list and shows wrong output for even number of nodes. Please help what is the problem in the code and reason why it is happening?
public static class Node
{
int data;
Node next;
}
public static class LinkedList
{
Node head;
Node tail;
int size;
// many other member functions
private void reversePRHelper(Node node , Node prev)
{
if(node == null)
{
return;
}
Node Next = node.next;
node.next = prev;
prev = node;
reversePRHelper(Next , prev);
Node temp = this.head;
this.head = this.tail;
this.tail = temp;
}
public void reversePR()
{
reversePRHelper(head,null);
}
}
The bug in your code is that these three lines:
Node temp = this.head;
this.head = this.tail;
this.tail = temp;
should only be executed once, at the end, and not for each recursive call. So if you move those three statements out of your reversePrHelper method and into your reversePR method, your code will work.
private void reversePRHelper(Node node , Node prev)
{
if(node != null)
{
return;
}
Node Next = node.next;
node.next = prev;
prev = node;
reversePRHelper(Next , prev);
}
public void reversePR()
{
reversePRHelper(head,null);
Node temp = this.head;
this.head = this.tail;
this.tail = temp;
}
For me it is unclear however why you keep the tail as an attribute, since you can't navigate anywhere from the tail, as it has no next value. It would be different if your nodes would keep a reference to the previous element as well, but then it would be a double linked list.

Reverse Linked-List Recursive

I've traced through my code to reverse a linked-list using recursion, and I cannot find anything wrong with it, but I know it does not work. Can anyone please explain why?
Node reverseLL (Node head) {
if(curr.next == null) {
head = curr;
return head;
}
Node curr = head.next;
prev = head;
head.next = prev;
head = next;
reverseLL(head.next);
}
Below is a working version of your code, added with some helping structures:
class LList {
Node head;
void reverse() {
head = rev(head, head.next);
}
private Node rev(Node node, Node next) {
if(next == null) return node; //return the node as head, if it hasn't got a next pointer.
if(node == this.head) node.next = null; //set the pointer of current head to null.
Node temp = next.next;
next.next = node; //reverse the pointer of node and next.
return rev(next, temp); //reverse pointer of next node and its next.
}
}
class Node {
int val;
Node next;
public Node(int val, Node next) {
this.val = val;
this.next = next;
}
}
You need to call reverseLL(head.next) before the switching, to traverse down the list and start from the last node upwards. This requires some more changes though.
There are two possible implementation.
First one with a pointer to the head (a class attribute) within your class
class Solution:
head: Optional[ListNode]
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
if node == None:
return node
if node.next == None:
self.head = node
return
self.reverseList(node.next)
q = node.next
q.next = node
node.next = None
return self.head
Second solution, does not rely on a class attribute to conserve the head once you find it. It returns the pointer to the head through the recursive calls stack
def reverseList(head):
# Empty list is always None
if not head:
return None
# List of length 1 is already reversed
if not head.next:
return head
next = head.next
head.next = None
rest = reverseList(next)
next.next = head
return rest

Why does this linked list insert code work, and the other code doesn't?

I'm learning linked lists in Java and I don't understand why this doesn't work:
public static Node insert(Node head, int data) {
if (head == null) return new Node(data);
else {
Node tail = head;
while (tail != null) tail = tail.next;
tail = new Node(data);
return head;
}
}
While this works very well:
public static Node insert(Node head, int data) {
if (head == null) return new Node(data);
else {
Node tail = head;
while (tail.next != null) tail = tail.next;
tail.next = new Node(data);
return head;
}
}
In both codes the null end nodes are instantiated. Why does not this produce the same result?
The Node class is as follows:
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
In the first case you are creating a new Node but not connecting it at anything, so it will just be detached from the list.
In the second case you are creating a new Node and connecting it to your actual tail Node, so it will be attached to the list.
Here a graphical representation:
while (tail != null) tail = tail.next;
The loop terminates when tail.next is null.
Then you do this:
tail = new Node(data);
Which leaves the next pointer of the last non-null tail to be null.
[head]---[1 (head.next)]---[2 (1.next)]---...---...---[last]---[nil (last.next)]
Change your Node class to below.
class Node {
int data;
Node next;
Node(int d) {
this.data = d;
this.next = null;
}
}
Set your head to new node in case you are inserting the first node.
public static Node insert(Node head, int data) {
if (head == null) {
head = new Node(data);
return head;
}
else {
Node tail = head;
while (tail.next != null) tail = tail.next;
tail.next = new Node(data);
return head;
}
}
The reason why your first case is not working because below will attach the node not after it rather you are creating a new node altogether and assigning it to your current pointed node.
while (tail != null) tail = tail.next;
tail = new Node(data);

error in deleting a node from singly linked circular linked list in Java

I am having some trouble in deleting a node fro a circular linked list specifically deleting the head node.I tried to debug the code and problem that i found out was that the head node is not getting updated after deletion.that means if my list is 1->2->3->1(the 1 at the end here is actually the repetition of head node 1 to show circular link list ) and after trying to delete '1' the list becomes 1->2->3->2...So basically the the head node is not getting updated and hence when I try to print this linked list it enters infinite loop as the head node is encountered only once and the stopping condition is nover met again. below is the code which I have written for deletion
public class cirlinklist {
private int data;
private cirlinklist next;
private cirlinklist head;
public cirlinklist()
{
data = 0;
next = this;
}
public cirlinklist(int val)
{
data = val;
next = this;
}
public void cirlist(int val)
{
cirlinklist node = new cirlinklist(val);
if(this.next == this) //only one node present
{
node.next = this;
this.next = node;
}
else
{
cirlinklist temp = this.next;
//cirlinklist head = this;
/*while(node != head)
node = node.next;*/
node.next = temp.next; //adding after the last added node.For adding before last added node change to temp here and temp.next in next line
this.next.next = node;
}
}
public void printlist()
{
//cirlinklist head = this; //start node
cirlinklist node = this; //node for traversing and printing
System.out.println("Circular Link list data is:");
do
{
System.out.println(node.data);
node = node.next;
}
while(node != head);
System.out.println(node.data);
}
public void check()
{
}
public cirlinklist delete(int val)
{
head = this;
cirlinklist node = head;
cirlinklist node2 = node;
if(head.data == val) //if the node to be deleted is head node
{
//this = this.next;
while(node.next != head) //iterate till the last node i.e. the node which is pointing to head
{
node = node.next;
}
node.next = node.next.next; // update current node pointer to next node of head
//node = node.next;
head = head.next; //update head node
/*this.next = head.next.next;
this.data = head.next.data;*/
return this;
}
else // if node to be deleted is other than head node
{
while(node.data != val) // find the node
{
node = node.next;
node2.next = node;
}
node2.next = node.next; //updating next field of previous node to next of current node.current node deleted
node = null;
return this;
}
}
public static void main(String [] args)
{
cirlinklist obj = new cirlinklist(1);
cirlinklist obj2 = new cirlinklist();
//obj.cirlist(1);
obj.cirlist(2);
obj.cirlist(3);
obj.printlist();
obj2 = obj.delete(1);
System.out.println("Circular list after deletion is");
obj2.printlist();
}
}
Please tell me where I am going wrong
if(head.data == val) //if the node to be deleted is head node
{
//this = this.next;
while(node.next != head) //iterate till the last node i.e. the node which is pointing to head
{
node = node.next;
}
node.next = node.next.next; // update current node pointer to next node of head
//node = node.next;
head = head.next; //update head node
}
In this code, where is the head pointing to after
node.next = node.next.next ?
may be the problem lies there.
Since your code has changed quite a bit since this answer was posted, I am starting fresh. I can solve your problem as it exists currently, but you do have some issues with your list design that I will mention and suggest you redesign what you have.
First, your print function is breaking because you don't have anything that sets head, which you are using to determine when to keep printing.
Modify your constructors to:
public cirlinklist()
{
data = 0;
next = this;
head = this;
}
public cirlinklist(int val)
{
data = val;
next = this;
head = this;
}
Second, your delete function needs to return head since that's what you're modifying in that function.
I've posted the cleaner function here:
public cirlinklist delete(int val)
{
cirlinklist node = head;
if(head.data == val) //if the node to be deleted is head node
{
//this = this.next;
while(node.next != head) //iterate till the last node i.e. the node which is pointing to head
{
node = node.next;
}
node.next = node.next.next; // update current node pointer to next node of head
//node = node.next;
head = head.next; //update head node
/*this.next = head.next.next;
this.data = head.next.data;*/
return this;
}
else // if node to be deleted is other than head node
{
cirlinklist prev = node; // track previous node from current (node)
while(node.data != val) // find the node
{
prev = node;
node = node.next;
}
prev.next = node.next; //updating next field of previous node to next of current node.current node deleted
return head;
}
}
This should get you what you want.
However, there is a problem that you're not yet seeing, in that if you try to return head and then hope it's a copy of the list, it's not. You're actually modifying the head list and then distributing it to some other method when it returns, meaning that cirlist obj2 = obj.delete(1); is not going to give you a new copy of the deleted list, leaving obj untouched. You can see this if you add another delete operation after this one and print.
That being said, I modified the function to react properly when deleting a node in the middle.
One other thing you might also want to test for, is removing the tail node, as you might experience problems with that case too.
The last thing I would suggest is you redefine your data structures. You're using the identifier node in this case to represent a list node, when in fact, as you've got them defined, are actually lists themselves. A linked-list as is typically defined, is a bunch of nodes linked together, the entire collection being the list.
If you create a data structure to represent the node, that is, it's an object that has a data element, and a pointer to the next node, your list can be in a different class entirely and you can operate on the nodes while preserving only a single copy of the list, that you can control and copy with greater ease.
Something like this:
public class ListNode {
public int data;
public ListNode next = null;
public ListNode() {
data = 0;
}
public ListNode(int data) {
this.data = data;
}
public ListNode(ListNode node) {
if ( node != null) {
this.data = node.data;
this.next = node.next;
}
}
}
Then you can have another class that actually provides the operations
public class CircularLinkedList {
public ListNode head;
public CircularLinkedList(...) {}
public void addToList(int data) {}
public void deleteFromList(int data) {}
... // and so-on
}
The head in this case, is your list, and any time you make changes or need to manipulate it, you can define functions that will do so in terms of head and then act appropriately.
Good luck to you

Reversing a linked list in Java, recursively

I have been working on a Java project for a class for a while now. It is an implementation of a linked list (here called AddressList, containing simple nodes called ListNode). The catch is that everything would have to be done with recursive algorithms. I was able to do everything fine sans one method: public AddressList reverse()
ListNode:
public class ListNode{
public String data;
public ListNode next;
}
Right now my reverse function just calls a helper function that takes an argument to allow recursion.
public AddressList reverse(){
return new AddressList(this.reverse(this.head));
}
With my helper function having the signature of private ListNode reverse(ListNode current).
At the moment, I have it working iteratively using a stack, but this is not what the specification requires. I had found an algorithm in C that recursively reversed and converted it to Java code by hand, and it worked, but I had no understanding of it.
Edit: Nevermind, I figured it out in the meantime.
private AddressList reverse(ListNode current, AddressList reversedList){
if(current == null)
return reversedList;
reversedList.addToFront(current.getData());
return this.reverse(current.getNext(), reversedList);
}
While I'm here, does anyone see any problems with this route?
There's code in one reply that spells it out, but you might find it easier to start from the bottom up, by asking and answering tiny questions (this is the approach in The Little Lisper):
What is the reverse of null (the empty list)? null.
What is the reverse of a one element list? the element.
What is the reverse of an n element list? the reverse of the rest of the list followed by the first element.
public ListNode Reverse(ListNode list)
{
if (list == null) return null; // first question
if (list.next == null) return list; // second question
// third question - in Lisp this is easy, but we don't have cons
// so we grab the second element (which will be the last after we reverse it)
ListNode secondElem = list.next;
// bug fix - need to unlink list from the rest or you will get a cycle
list.next = null;
// then we reverse everything from the second element on
ListNode reverseRest = Reverse(secondElem);
// then we join the two lists
secondElem.next = list;
return reverseRest;
}
I was asked this question at an interview and was annoyed that I fumbled with it since I was a little nervous.
This should reverse a singly linked list, called with reverse(head,NULL);
so if this were your list:
1->2->3->4->5->null
it would become:
5->4->3->2->1->null
//Takes as parameters a node in a linked list, and p, the previous node in that list
//returns the head of the new list
Node reverse(Node n,Node p){
if(n==null) return null;
if(n.next==null){ //if this is the end of the list, then this is the new head
n.next=p;
return n;
}
Node r=reverse(n.next,n); //call reverse for the next node,
//using yourself as the previous node
n.next=p; //Set your next node to be the previous node
return r; //Return the head of the new list
}
edit: ive done like 6 edits on this, showing that it's still a little tricky for me lol
I got half way through (till null, and one node as suggested by plinth), but lost track after making recursive call. However, after reading the post by plinth, here is what I came up with:
Node reverse(Node head) {
// if head is null or only one node, it's reverse of itself.
if ( (head==null) || (head.next == null) ) return head;
// reverse the sub-list leaving the head node.
Node reverse = reverse(head.next);
// head.next still points to the last element of reversed sub-list.
// so move the head to end.
head.next.next = head;
// point last node to nil, (get rid of cycles)
head.next = null;
return reverse;
}
Here's yet another recursive solution. It has less code within the recursive function than some of the others, so it might be a little faster. This is C# but I believe Java would be very similar.
class Node<T>
{
Node<T> next;
public T data;
}
class LinkedList<T>
{
Node<T> head = null;
public void Reverse()
{
if (head != null)
head = RecursiveReverse(null, head);
}
private Node<T> RecursiveReverse(Node<T> prev, Node<T> curr)
{
Node<T> next = curr.next;
curr.next = prev;
return (next == null) ? curr : RecursiveReverse(curr, next);
}
}
The algo will need to work on the following model,
keep track of the head
Recurse till end of linklist
Reverse linkage
Structure:
Head
|
1-->2-->3-->4-->N-->null
null-->1-->2-->3-->4-->N<--null
null-->1-->2-->3-->4<--N<--null
null-->1-->2-->3<--4<--N<--null
null-->1-->2<--3<--4<--N<--null
null-->1<--2<--3<--4<--N<--null
null<--1<--2<--3<--4<--N
|
Head
Code:
public ListNode reverse(ListNode toBeNextNode, ListNode currentNode)
{
ListNode currentHead = currentNode; // keep track of the head
if ((currentNode==null ||currentNode.next==null )&& toBeNextNode ==null)return currentHead; // ignore for size 0 & 1
if (currentNode.next!=null)currentHead = reverse(currentNode, currentNode.next); // travarse till end recursively
currentNode.next = toBeNextNode; // reverse link
return currentHead;
}
Output:
head-->12345
head-->54321
I think this is more cleaner solution, which resembles LISP
// Example:
// reverse0(1->2->3, null) =>
// reverse0(2->3, 1) =>
// reverse0(3, 2->1) => reverse0(null, 3->2->1)
// once the first argument is null, return the second arg
// which is nothing but the reveresed list.
Link reverse0(Link f, Link n) {
if (f != null) {
Link t = new Link(f.data1, f.data2);
t.nextLink = n;
f = f.nextLink; // assuming first had n elements before,
// now it has (n-1) elements
reverse0(f, t);
}
return n;
}
I know this is an old post, but most of the answers are not tail recursive i.e. they do some operations after returning from the recursive call, and hence not the most efficient.
Here is a tail recursive version:
public Node reverse(Node previous, Node current) {
if(previous == null)
return null;
if(previous.equals(head))
previous.setNext(null);
if(current == null) { // end of list
head = previous;
return head;
} else {
Node temp = current.getNext();
current.setNext(previous);
reverse(current, temp);
}
return null; //should never reach here.
}
Call with:
Node newHead = reverse(head, head.getNext());
void reverse(node1,node2){
if(node1.next!=null)
reverse(node1.next,node1);
node1.next=node2;
}
call this method as reverse(start,null);
public Node reverseListRecursive(Node curr)
{
if(curr == null){//Base case
return head;
}
else{
(reverseListRecursive(curr.next)).next = (curr);
}
return curr;
}
public void reverse() {
head = reverseNodes(null, head);
}
private Node reverseNodes(Node prevNode, Node currentNode) {
if (currentNode == null)
return prevNode;
Node nextNode = currentNode.next;
currentNode.next = prevNode;
return reverseNodes(currentNode, nextNode);
}
Reverse by recursive algo.
public ListNode reverse(ListNode head) {
if (head == null || head.next == null) return head;
ListNode rHead = reverse(head.next);
rHead.next = head;
head = null;
return rHead;
}
By iterative
public ListNode reverse(ListNode head) {
if (head == null || head.next == null) return head;
ListNode prev = null;
ListNode cur = head
ListNode next = head.next;
while (next != null) {
cur.next = prev;
prev = cur;
cur = next;
next = next.next;
}
return cur;
}
public static ListNode recRev(ListNode curr){
if(curr.next == null){
return curr;
}
ListNode head = recRev(curr.next);
curr.next.next = curr;
curr.next = null;
// propogate the head value
return head;
}
This solution demonstrates that no arguments are required.
/**
* Reverse the list
* #return reference to the new list head
*/
public LinkNode reverse() {
if (next == null) {
return this; // Return the old tail of the list as the new head
}
LinkNode oldTail = next.reverse(); // Recurse to find the old tail
next.next = this; // The old next node now points back to this node
next = null; // Make sure old head has no next
return oldTail; // Return the old tail all the way back to the top
}
Here is the supporting code, to demonstrate that this works:
public class LinkNode {
private char name;
private LinkNode next;
/**
* Return a linked list of nodes, whose names are characters from the given string
* #param str node names
*/
public LinkNode(String str) {
if ((str == null) || (str.length() == 0)) {
throw new IllegalArgumentException("LinkNode constructor arg: " + str);
}
name = str.charAt(0);
if (str.length() > 1) {
next = new LinkNode(str.substring(1));
}
}
public String toString() {
return name + ((next == null) ? "" : next.toString());
}
public static void main(String[] args) {
LinkNode head = new LinkNode("abc");
System.out.println(head);
System.out.println(head.reverse());
}
}
Here is a simple iterative approach:
public static Node reverse(Node root) {
if (root == null || root.next == null) {
return root;
}
Node curr, prev, next;
curr = root; prev = next = null;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
And here is a recursive approach:
public static Node reverseR(Node node) {
if (node == null || node.next == null) {
return node;
}
Node next = node.next;
node.next = null;
Node remaining = reverseR(next);
next.next = node;
return remaining;
}
As Java is always pass-by-value, to recursively reverse a linked list in Java, make sure to return the "new head"(the head node after reversion) at the end of the recursion.
static ListNode reverseR(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode first = head;
ListNode rest = head.next;
// reverse the rest of the list recursively
head = reverseR(rest);
// fix the first node after recursion
first.next.next = first;
first.next = null;
return head;
}
PointZeroTwo has got elegant answer & the same in Java ...
public void reverseList(){
if(head!=null){
head = reverseListNodes(null , head);
}
}
private Node reverseListNodes(Node parent , Node child ){
Node next = child.next;
child.next = parent;
return (next==null)?child:reverseListNodes(child, next);
}
public class Singlelinkedlist {
public static void main(String[] args) {
Elem list = new Elem();
Reverse(list); //list is populate some where or some how
}
//this is the part you should be concerned with the function/Method has only 3 lines
public static void Reverse(Elem e){
if (e!=null)
if(e.next !=null )
Reverse(e.next);
//System.out.println(e.data);
}
}
class Elem {
public Elem next; // Link to next element in the list.
public String data; // Reference to the data.
}
public Node reverseRec(Node prev, Node curr) {
if (curr == null) return null;
if (curr.next == null) {
curr.next = prev;
return curr;
} else {
Node temp = curr.next;
curr.next = prev;
return reverseRec(curr, temp);
}
}
call using: head = reverseRec(null, head);
What other guys done , in other post is a game of content, what i did is a game of linkedlist, it reverse the LinkedList's member not reverse of a Value of members.
Public LinkedList reverse(LinkedList List)
{
if(List == null)
return null;
if(List.next() == null)
return List;
LinkedList temp = this.reverse( List.next() );
return temp.setNext( List );
}
package com.mypackage;
class list{
node first;
node last;
list(){
first=null;
last=null;
}
/*returns true if first is null*/
public boolean isEmpty(){
return first==null;
}
/*Method for insertion*/
public void insert(int value){
if(isEmpty()){
first=last=new node(value);
last.next=null;
}
else{
node temp=new node(value);
last.next=temp;
last=temp;
last.next=null;
}
}
/*simple traversal from beginning*/
public void traverse(){
node t=first;
while(!isEmpty() && t!=null){
t.printval();
t= t.next;
}
}
/*static method for creating a reversed linked list*/
public static void reverse(node n,list l1){
if(n.next!=null)
reverse(n.next,l1);/*will traverse to the very end*/
l1.insert(n.value);/*every stack frame will do insertion now*/
}
/*private inner class node*/
private class node{
int value;
node next;
node(int value){
this.value=value;
}
void printval(){
System.out.print(value+" ");
}
}
}
The solution is:
package basic;
import custom.ds.nodes.Node;
public class RevLinkedList {
private static Node<Integer> first = null;
public static void main(String[] args) {
Node<Integer> f = new Node<Integer>();
Node<Integer> s = new Node<Integer>();
Node<Integer> t = new Node<Integer>();
Node<Integer> fo = new Node<Integer>();
f.setNext(s);
s.setNext(t);
t.setNext(fo);
fo.setNext(null);
f.setItem(1);
s.setItem(2);
t.setItem(3);
fo.setItem(4);
Node<Integer> curr = f;
display(curr);
revLL(null, f);
display(first);
}
public static void display(Node<Integer> curr) {
while (curr.getNext() != null) {
System.out.println(curr.getItem());
System.out.println(curr.getNext());
curr = curr.getNext();
}
}
public static void revLL(Node<Integer> pn, Node<Integer> cn) {
while (cn.getNext() != null) {
revLL(cn, cn.getNext());
break;
}
if (cn.getNext() == null) {
first = cn;
}
cn.setNext(pn);
}
}
static void reverseList(){
if(head!=null||head.next!=null){
ListNode tail=head;//head points to tail
ListNode Second=head.next;
ListNode Third=Second.next;
tail.next=null;//tail previous head is poiniting null
Second.next=tail;
ListNode current=Third;
ListNode prev=Second;
if(Third.next!=null){
while(current!=null){
ListNode next=current.next;
current.next=prev;
prev=current;
current=next;
}
}
head=prev;//new head
}
}
class ListNode{
public int data;
public ListNode next;
public int getData() {
return data;
}
public ListNode(int data) {
super();
this.data = data;
this.next=null;
}
public ListNode(int data, ListNode next) {
super();
this.data = data;
this.next = next;
}
public void setData(int data) {
this.data = data;
}
public ListNode getNext() {
return next;
}
public void setNext(ListNode next) {
this.next = next;
}
}
private Node ReverseList(Node current, Node previous)
{
if (current == null) return null;
Node originalNext = current.next;
current.next = previous;
if (originalNext == null) return current;
return ReverseList(originalNext, current);
}
//this function reverses the linked list
public Node reverseList(Node p) {
if(head == null){
return null;
}
//make the last node as head
if(p.next == null){
head.next = null;
head = p;
return p;
}
//traverse to the last node, then reverse the pointers by assigning the 2nd last node to last node and so on..
return reverseList(p.next).next = p;
}
//Recursive solution
class SLL
{
int data;
SLL next;
}
SLL reverse(SLL head)
{
//base case - 0 or 1 elements
if(head == null || head.next == null) return head;
SLL temp = reverse(head.next);
head.next.next = head;
head.next = null;
return temp;
}
Inspired by an article discussing immutable implementations of recursive data structures I put an alternate solution together using Swift.
The leading answer documents solution by highlighting the following topics:
What is the reverse of nil (the empty list)?
Does not matter here, because we have nil protection in Swift.
What is the reverse of a one element list?
The element itself
What is the reverse of an n element list?
The reverse of the second element on followed by the first element.
I have called these out where applicable in the solution below.
/**
Node is a class that stores an arbitrary value of generic type T
and a pointer to another Node of the same time. This is a recursive
data structure representative of a member of a unidirectional linked
list.
*/
public class Node<T> {
public let value: T
public let next: Node<T>?
public init(value: T, next: Node<T>?) {
self.value = value
self.next = next
}
public func reversedList() -> Node<T> {
if let next = self.next {
// 3. The reverse of the second element on followed by the first element.
return next.reversedList() + value
} else {
// 2. Reverse of a one element list is itself
return self
}
}
}
/**
#return Returns a newly created Node consisting of the lhs list appended with rhs value.
*/
public func +<T>(lhs: Node<T>, rhs: T) -> Node<T> {
let tail: Node<T>?
if let next = lhs.next {
// The new tail is created recursively, as long as there is a next node.
tail = next + rhs
} else {
// If there is not a next node, create a new tail node to append
tail = Node<T>(value: rhs, next: nil)
}
// Return a newly created Node consisting of the lhs list appended with rhs value.
return Node<T>(value: lhs.value, next: tail)
}
Reversing the linked list using recursion. The idea is adjusting the links by reversing the links.
public ListNode reverseR(ListNode p) {
//Base condition, Once you reach the last node,return p
if (p == null || p.next == null) {
return p;
}
//Go on making the recursive call till reach the last node,now head points to the last node
ListNode head = reverseR(p.next); //Head points to the last node
//Here, p points to the last but one node(previous node), q points to the last node. Then next next step is to adjust the links
ListNode q = p.next;
//Last node link points to the P (last but one node)
q.next = p;
//Set the last but node (previous node) next to null
p.next = null;
return head; //Head points to the last node
}
public void reverseLinkedList(Node node){
if(node==null){
return;
}
reverseLinkedList(node.next);
Node temp = node.next;
node.next=node.prev;
node.prev=temp;
return;
}
public void reverse(){
if(isEmpty()){
return;
}
Node<T> revHead = new Node<T>();
this.reverse(head.next, revHead);
this.head = revHead;
}
private Node<T> reverse(Node<T> node, Node<T> revHead){
if(node.next == null){
revHead.next = node;
return node;
}
Node<T> reverse = this.reverse(node.next, revHead);
reverse.next = node;
node.next = null;
return node;
}
Here is a reference if someone is looking for Scala implementation:
scala> import scala.collection.mutable.LinkedList
import scala.collection.mutable.LinkedList
scala> def reverseLinkedList[A](ll: LinkedList[A]): LinkedList[A] =
ll.foldLeft(LinkedList.empty[A])((accumulator, nextElement) => nextElement +: accumulator)
reverseLinkedList: [A](ll: scala.collection.mutable.LinkedList[A])scala.collection.mutable.LinkedList[A]
scala> reverseLinkedList(LinkedList("a", "b", "c"))
res0: scala.collection.mutable.LinkedList[java.lang.String] = LinkedList(c, b, a)
scala> reverseLinkedList(LinkedList("1", "2", "3"))
res1: scala.collection.mutable.LinkedList[java.lang.String] = LinkedList(3, 2, 1)

Categories

Resources