Removing "links" from a LinkedList? - java

I have a LinkedList (Own code for the LinkedList) with char's in it. This is the complete list: ['a','b','I','d','R','A','7','p'].
I am trying to write a method which will deleting all characters that is NOT a upper case letter. After running the method, the LinkedList should look like this ['I','R','A'].
But after running my code I get the same list as return, this list: ['a','b','I','d','R','A','7','p'].
Here is my code for the method:
public static ListNode copyUpperCase(ListNode head) {
ListNode ptr = head;
while(!isEmpty(ptr.next)){
if(!Character.isUpperCase(ptr.element)){
ptr = ptr.next.next;
//System.out.println(ptr.element);
}
ptr = ptr.next;
}
return head;
}
Here is isEmpty():
public static boolean isEmpty(ListNode l) {
if ( l == null )
throw new ListsException("Lists: null passed to isEmpty");
return l.next == null;
}
Here is ListNode:
public class ListNode {
public char element;
public ListNode next;
}
I can see that the search part is working, but I can't get the deleting the node part right, any suggestions?

public static ListNode copyUpperCase(ListNode head) {
ListNode ptr = head;
while(!isEmpty(ptr.next)){
if(!Character.isUpperCase(ptr.element)){
ptr.next = ptr.next.next;
//System.out.println(ptr.element);
}
ptr = ptr.next;
}
return head;
}
You need to "CHANGE" the list, so you just missed the assignment to the element and not the the local variable
THIS code will not work however, as this just assign to the next element, without looking if next element actully is a good one, and then skips to that one
Edit: full working code
class ListNode {
public ListNode(char element,ListNode next ) {
this.element = element;
this.next = next;
}
public char element;
public ListNode next;
void print() {
System.out.print(this.element+",");
if(this.next != null) {
this.next.print();
}
else {
System.out.println("");
}
}
}
public class main {
//Imo you should only check if this elem is a null one, as a null means empty, a null on next only means that it's the last elem, but will still contain data
public static boolean isEmpty(ListNode l) {
return l == null;
}
public static ListNode getNextUpper(ListNode head) {
while(!isEmpty(head)){
if(Character.isUpperCase(head.element)) {
return head;
}
head = head.next;
}
return null;
}
public static ListNode copyUpperCase(ListNode head) {
ListNode newhead = getNextUpper(head);
ListNode temp = newhead;
while(!isEmpty(temp)){
temp.next = getNextUpper(temp.next);
temp = temp.next;
}
return newhead;
}
public static void main(String[] args) {
ListNode t = new ListNode('a' , new ListNode('b' , new ListNode('I', new ListNode('d', new ListNode('R', new ListNode('A', new ListNode('7', new ListNode('p',null))))))));
t.print();
ListNode newt = copyUpperCase(t);
newt.print();
}
}

ptr is a local variable, so
ptr = ptr.next.next;
doesn't modify your linked list.
You should modify ptr.next instead. Besides that, you may have to modify head, if the original head doesn't refer to an upper case letter.
Something like this should work :
// find the first valid (upper case) element and set head to refer to it
while (!Character.isUpperCase(head.element) && head != null)
head = head.next;
ListNode ptr = head;
if (ptr != null)
// eliminate all non-upper case elements
while(!isEmpty(ptr.next)){
if(!Character.isUpperCase(ptr.next.element)){
ptr.next = ptr.next.next;
}
ptr = ptr.next;
}
}
return head;

Related

Not printing elements when value of n is equal to size of linked list

I am doing the program for removing nth element from end of the linked list. But problem is that when my size of lined list is equal to n then it is not returning head.next. Where I am doing wrong?
class Main{
static class Node {
int data;
Node next;
Node(int data){
this.data = data;
this.next = null;
}
}
Node head = null;
public void addFirst(int data) {
Node newnode = new Node(data);
if(head ==null){
head = newnode;
return;
}
newnode.next = head;
head = newnode;
}
//print list
public void PrintLL() {
Node n = head;
if(n.next==null){
System.out.println("NULL");
return;
}
while(n!=null){
System.out.print(n.data+ " --> ");
n= n.next;
}
}
//Find nth node from last
public Node RemoveNthNode(Node head,int nth){
if(head.next==null){
return null;
}
int size=0;
Node curNode=head;
while(curNode!=null){
curNode = curNode.next;
size++;
}
if(nth==size){
return head.next;
}
Node prevnode = head;
int i=1;
while(i<size-nth){
prevnode=prevnode.next;
i++;
}
prevnode.next = prevnode.next.next;
return head;
}
public static void main(String[] args) {
Main ll = new Main();
ll.addFirst(90);
ll.addFirst(40);
ll.addFirst(45);
System.out.println("\n");
ll.RemoveNthNode(ll.head, 3);
ll.PrintLL();
}
}
I tried the code that I have posted but it is not printing when n equal size of LL.
The reason is that although your function RemoveNthNode returns the head after the removal, the caller (in main) ignores the returned value, so that it never sees a change to head. The confusion may also be caused by the parameter that has the name head, which shadows the head property of the class instance.
As it is not intuitive that the caller needs to provide head as argument, while you would expect that the method would know what the head of the list is, I suggest to make it a void method which doesn't take the head argument.
You should also take care of the case where head is null.
Your PrintLL has a problem too: it doesn't print the node when the list has just one node.
Corrected code:
public void PrintLL() {
Node n = head;
while(n!=null){
System.out.print(n.data+ " --> ");
n= n.next;
}
System.out.println("NULL");
}
public void RemoveNthNode(int nth){
if(head == null || head.next==null){
head = null;
return;
}
int size=0;
Node curNode=head;
while(curNode!=null) {
curNode = curNode.next;
size++;
}
if(nth==size){
head = head.next;
return;
}
Node prevnode = head;
int i=1;
while(i<size-nth){
prevnode=prevnode.next;
i++;
}
prevnode.next = prevnode.next.next;
}
public static void main(String[] args) {
Main ll = new Main();
ll.addFirst(90);
ll.addFirst(40);
ll.addFirst(45);
ll.PrintLL();
ll.RemoveNthNode(3);
ll.PrintLL();
}

How can I get my next pointer of my LinkedList class without using built in function?

I'm newbie in programming and I'm practicing a Java Programming Language. I was having a rough day in finding the solution of my program because I cannot get my "next" pointer and I really want to print my last value. Could someone help me to fix this and explain to me? Thank you in advance. Here's my code.
Note: The output of my program is 5.
public class Node {
private int data;
private Node next;
public Node (int data){
this.data = data;
}
public int getData() {
return this.data;
}
public void setNext(Node n) {
this.next = n;
}
public Node getNext() {
return this.next;
}
}
public class LinkedList {
private static Node head, next;
public LinkedList (int data) {
head = new Node (data);
}
public void addLast(int data) {
Node n = new Node (data);
if (head == null) {
head = n;
}
else {
Node temp = head;
temp.setNext(next);
while (temp.getNext() != null) {
temp = temp.getNext();
}
Node t = temp.getNext();
t = n;
}
}
public void printList() {
head.setNext(next);
while (head.getNext() != null) {
System.out.println(head.getData());
head = head.getNext();
}
System.out.println(head.getData());
}
public static void main(String[] args) {
LinkedList l = new LinkedList(5);
l.addLast(7);
l.printList();
}
}
I suggest following two amendment to your code.
with following else block in addLast method.
Node temp = head;
temp.setNext(next); // this line causing the next object to be set to null all the time. commenting this line will help in making sure the follwing loop reaches to end of the list, otherwise the while loop will always exit without any iteration.
while (temp.getNext() != null) {
temp = temp.getNext();
}
Node t = temp.getNext();
t = n; // this will also not change the linking. Its basically assigned a new value to t.
use following suggestion
Node temp = head;
while (temp.getNext() != null) {
temp = temp.getNext();
}
// now we reached end of list and temp.next is null.
// assign newly createdd node to temp.next
temp.setNext(n);
While iterating the element in printList same problem exist as mentioned in point 1. try to use following suggestion for printList method.
// head.setNext(next); // This line will always set head.next to null and whole list will be lost. Instead of this use following line
Node temp = head;
while (temp.getNext() != null) { // here if you use head its position will move to end. So use temp variable for iteration
System.out.println(temp.getData());
temp= temp.getNext();
}
System.out.println(temp.getData());
You may also need to study list iteration algorithm to have better understanding.
I've made some amendments to make your code work. The If statement in your addLast method:
if (head == null) {
is redundant since your LinkedList can only be initialized by passing some data, hence head will never be null, it will always point to the Node containing data
Also the line
head.setNext(next);
in your printList() was problematic, it was always pointing to null
public class LinkedList {
private static Node head, next;
public LinkedList(int data) {
head = new Node(data);
}
public void addLast(int data) {
Node n = new Node(data);
Node temp = head;
temp.setNext(next);
while (temp.getNext() != null) {
temp = temp.getNext();
}
temp.setNext(n);
}
public void printList() {
while (head.getNext() != null) {
System.out.println(head.getData());
head = head.getNext();
}
System.out.println(head.getData());
}
public static void main(String[] args) {
LinkedList l = new LinkedList(5);
l.addLast(7);
l.printList();
}
}
TL;DR:
You set null as the next node in your printList() method;
Your addLast does not work either (you do not set the next node (see details below);
You should never set the node (or do any logical alteration whatsoever) in your print method. Print must just print, as the name suggests, and it should not contain any side-effect, amending your data structure. That is: you have to clearly separate your concerns.
In your current addLast, you do:
public void addLast(int data) {
Node n = new Node (data);
if (head == null) {
head = n;
}
else {
Node temp = head;
temp.setNext(next);
while (temp.getNext() != null) {
temp = temp.getNext();
}
Node t = temp.getNext();
t = n;
}
}
which means, that when your temp's next node is null, you never add the Node you instantiate with your int argument.
Change the else block as follows:
else {
Node temp = head;
temp.setNext(next);
while (temp.getNext() != null) {
temp = temp.getNext();
}
temp.setNext(n);
//two redundant lines removed
}
Correspondingly, remove head.setNext(next); (and possibly unnecessary System.out.println() statement) from your printList() method.
P. S. I would really recommend you to spend some time on the Linked List Data Structure (Data Structure, and not the Java code), as your current design, shows that you need to have a better grasp of it.

java: Memory Limit Exceeded?

I write a code by java in leetCode, this is the link:
https://leetcode.com/problems/reverse-linked-list/description/
it shows "Memory Limit Exceeded", can anyone explain why?(you can just paste my code to the above link to see the error)
My code is as follows:
public static class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode reverseList(ListNode head) {
if(head ==null)
return head;
if(head.next ==null){
return head;
}
Stack<ListNode> mStack =new Stack<>();
while(head!=null){
mStack.push(head);
head = head.next;
}
ListNode mNode = new ListNode(0);
ListNode result =mNode;
while(!mStack.empty()){
ListNode temp = mStack.pop();;
mNode.next = temp;
mNode = mNode.next;
}
return result.next;
}
The problem is that, suppose the input is 1->2->3. Then what you will return is
3->2->1->2->1->2.....
This circular linked list will cause Memory Limit Exceeded when calling toString method.
To solve this, just set the next of original head to null.
This is because they expect you to do it in constant space complexity. A simple recursive solution would be :
class Solution {
public ListNode reverseList(ListNode head) {
if (head==null){
return head;
}
return reverseList(head,null);
}
public ListNode reverseList(ListNode current,ListNode prev){
if (current.next==null){
// we have reached the last node. This will be the new head
current.next = prev;
return current;
}
ListNode head = reverseList(current.next,current);
current.next=prev;
return head;
}
}

only print last two value of linked list

Here is my Node class
public class listNode {
String data;
listNode next;
public listNode(String data, listNode next) {
this.data = data;
this.next = next;
}
public String toString(){
return data;
}
}
Hers is my List class
public class List {
listNode head;
public List(){
head = null;
}
public void addLast(String target){
if(head == null){
head = new listNode(target,head);
}
while(head.next != null){
head = head.next;
}
head.next = new listNode(target,null);
}
}
print method:
public void print(){
while(head != null){
System.out.println(head.toString());
head = head.next;
}
}
When I use this method at main function, it always only print the last two value of the linked list, and I am so confused.
example:
l1.addLast("a");
l1.addLast("b");
l1.addLast("c");
it only prints
b,c
The below code is incorrect. You should not change the head object. Use a different object.
while(head.next != null){
head = head.next;
}
It should be like:
class List {
listNode head;
public List(){
head = null;
}
public void addLast(String target){
if(head == null){
head = new listNode(target,head);
}
else {
listNode last = head;
while(last.next != null){
last = last.next;
}
last.next = new listNode(target,null);
}
}
}
You have 2 mistakes.
public void addLast(String target){
if(head == null){
head = new listNode(target,head);
return; // Mistake 1 - you need to return here - nothing more is needed.
// If you don't return. addLast will create 2 listNode's for the first entry.
}
listNode h = head; // Mistake 2 - Use a temp instead of head. head will
//no longer point to the start otherwise.
while(h.next != null)
{
h = h.next;
}
h.next = new listNode(target,null);
}
The Mistakes are pointed to in the comments.
The first mistake isn't serious. The 2nd one is.

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